Source code for oci_policy_analysis.presentation.qt.policy_limits

"""Manual policy-limit entry with tenancy-specific Console and CLI guidance."""

import shlex

from PySide6.QtCore import Qt
from PySide6.QtGui import QFontDatabase
from PySide6.QtWidgets import (
    QApplication,
    QDialog,
    QDialogButtonBox,
    QFormLayout,
    QLineEdit,
    QPlainTextEdit,
    QPushButton,
    QVBoxLayout,
)

from oci_policy_analysis.application.services.policy_limits_service import PolicyLimitsService
from oci_policy_analysis.presentation.qt.widgets import label


[docs] class PolicyLimitsDialog(QDialog): """Collect verified limits for an offline snapshot without contacting OCI. Args: context: Current snapshot; its named cache is updated on explicit Apply. parent: Owning Qt page. Cancel never changes limits or files. """ def __init__(self, context, parent=None): super().__init__(parent) self.context = context self.setWindowTitle('Enter tenancy policy limits') self.setModal(True) self.resize(820, 600) layout = QVBoxLayout(self) repo = context.policy_repo layout.addWidget( label(f'Tenancy: {getattr(repo, "tenancy_name", None) or repo.tenancy_ocid or "Not recorded"}', 'eyebrow') ) layout.addWidget( label( 'This snapshot was not live loaded. Enter the actual values for its tenancy if you know them; no default is assumed. ' + ( 'Values will be saved with the active cache.' if getattr(repo, 'current_cache_name', '') else 'Values apply to this session. The source file and global settings will not be changed.' ), 'notice', wrap=True, ) ) form = QFormLayout() limits = getattr(repo, 'tenancy_policy_limits', {}) or {} self.policy_limit = QLineEdit(str(limits.get('policies_count') or '')) self.chain_limit = QLineEdit(str(limits.get('policy_statements_per_compartment_chain_count') or '')) form.addRow('Policies per tenancy', self.policy_limit) form.addRow('Statements per compartment hierarchy', self.chain_limit) layout.addLayout(form) layout.addWidget(label('Find the values in OCI', 'eyebrow')) layout.addWidget( label( 'Console: Open Limits, Quotas and Usage, select the tenancy and Identity service, ' 'then locate policies-count and policy-statements-per-compartment-chain-count. ' 'Use that tenancy’s actual values rather than a published default.', wrap=True, ) ) layout.addWidget( label( 'CLI: Run these commands using credentials and a region for the source tenancy. ' 'Replace TENANCY_OCID if the snapshot does not record it. Read the value field in each response.', wrap=True, ) ) tenancy_id = str(repo.tenancy_ocid or '') tenancy = shlex.quote(tenancy_id if tenancy_id.startswith('ocid1.tenancy.') else 'TENANCY_OCID') self.commands = QPlainTextEdit() self.commands.setReadOnly(True) fixed_font = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont) self.commands.setFont(fixed_font) self.commands.setStyleSheet(f'QPlainTextEdit {{ font-family: "{fixed_font.family()}"; }}') self.commands.setPlainText( '\n\n'.join( f'oci limits value list --compartment-id {tenancy} --service-name identity --name {name} --all' for name in ('policies-count', 'policy-statements-per-compartment-chain-count') ) ) layout.addWidget(self.commands, 1) copy = QPushButton('Copy CLI commands') copy.clicked.connect(lambda: QApplication.clipboard().setText(self.commands.toPlainText())) layout.addWidget(copy) documentation = label( '<a href="https://docs.oracle.com/en-us/iaas/Content/General/service-limits/default.htm">OCI service limits</a> · ' '<a href="https://docs.oracle.com/en-us/iaas/tools/oci-cli/latest/oci_cli_docs/cmdref/limits/value/list.html">CLI reference</a>', wrap=True, ) documentation.setTextFormat(Qt.TextFormat.RichText) documentation.setOpenExternalLinks(True) layout.addWidget(documentation) self.error = label('', 'notice', wrap=True) self.error.hide() layout.addWidget(self.error) self.buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Apply | QDialogButtonBox.StandardButton.Cancel) self.buttons.button(QDialogButtonBox.StandardButton.Apply).clicked.connect(self._apply) self.buttons.rejected.connect(self.reject) layout.addWidget(self.buttons) self.ensurePolished() if self.fontMetrics().height() > 20: self.resize(1060, 850) def _apply(self): try: PolicyLimitsService(self.context).apply_manual(self.policy_limit.text(), self.chain_limit.text()) except (ValueError, OSError) as exc: self.error.setText(str(exc)) self.error.show() return self.accept()