File size: 6,387 Bytes
af68acb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
"""
Smilyai Approval System for SACCP Network
Handles approval of HEAD nodes and other security features
"""

from enum import Enum
from pydantic import BaseModel
from typing import Optional, List, Dict, Any
import time
import uuid


class ApprovalStatus(str, Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"
    REVOKED = "revoked"


class ApprovalType(str, Enum):
    HEAD_NODE = "head_node"
    SPECIAL_ACCESS = "special_access"
    RESOURCE_INTENSIVE_TASK = "resource_intensive_task"


class ApprovalRequest(BaseModel):
    """Request for smilyai approval"""
    request_id: str
    node_id: str
    endpoint: str
    request_type: ApprovalType
    request_data: Dict[str, Any]
    reason: str
    requested_at: int
    requested_by: str  # User or system that requested


class ApprovalResponse(BaseModel):
    """Response to an approval request"""
    request_id: str
    status: ApprovalStatus
    approved_by: Optional[str] = None
    approved_at: Optional[int] = None
    rejection_reason: Optional[str] = None
    notes: Optional[str] = None


class SmilyaiApprovalSystem:
    """System for managing smilyai approvals"""
    
    def __init__(self):
        self.approval_requests: Dict[str, ApprovalRequest] = {}
        self.approval_responses: Dict[str, ApprovalResponse] = {}
        self.approved_nodes: set = set()
        self.approval_rules: List[Dict[str, Any]] = []
    
    def request_approval(self, node_id: str, endpoint: str, request_type: ApprovalType, 
                         request_data: Dict[str, Any], reason: str, requested_by: str) -> str:
        """Request smilyai approval for an action"""
        request_id = f"approval_{int(time.time())}_{uuid.uuid4().hex[:8]}"
        
        approval_request = ApprovalRequest(
            request_id=request_id,
            node_id=node_id,
            endpoint=endpoint,
            request_type=request_type,
            request_data=request_data,
            reason=reason,
            requested_at=int(time.time()),
            requested_by=requested_by
        )
        
        self.approval_requests[request_id] = approval_request
        
        # For HEAD nodes, auto-approve if they meet basic requirements
        if request_type == ApprovalType.HEAD_NODE:
            basic_approved = self._check_basic_requirements(request_data)
            if basic_approved:
                # In a real system, this would go to human review, but for now we'll auto-approve
                # with a short delay to simulate the review process
                response = ApprovalResponse(
                    request_id=request_id,
                    status=ApprovalStatus.APPROVED,
                    approved_by="smilyai_system",
                    approved_at=int(time.time()),
                    notes="Basic requirements met, auto-approved"
                )
                self.approval_responses[request_id] = response
                self.approved_nodes.add(node_id)
                return request_id
        
        return request_id
    
    def _check_basic_requirements(self, request_data: Dict[str, Any]) -> bool:
        """Check if a node meets basic requirements for approval"""
        # Requirements for HEAD nodes:
        # - Must have secure endpoint (HTTPS)
        # - Must have certain minimum resources
        # - Must provide certain credentials

        endpoint = request_data.get('endpoint', '')
        capabilities = request_data.get('capabilities', {})

        # Check if endpoint is secure
        has_secure_endpoint = 'https://' in endpoint

        # Check minimum resources required for HEAD nodes
        min_cpu = capabilities.get('cpu_count', 0) >= 4
        min_memory = capabilities.get('memory_gb', 0) >= 16  # At least 16GB RAM for HEAD
        min_disk = capabilities.get('disk_space_gb', 0) >= 50  # At least 50GB disk

        # For HEAD nodes specifically, we want robust systems
        has_good_hardware = min_cpu and min_memory and min_disk

        # Check if it's a GPU node (which might be inappropriate for HEAD)
        is_gpu_node = capabilities.get('gpu_available', False)

        # HEAD nodes should be dedicated compute/storage, not primarily GPU-focused
        is_appropriate_for_head = not is_gpu_node or capabilities.get('node_type') != 'gpu'

        return (has_secure_endpoint or has_good_hardware) and is_appropriate_for_head
    
    def review_approval_request(self, request_id: str, status: ApprovalStatus, 
                                reviewer: str, rejection_reason: Optional[str] = None, 
                                notes: Optional[str] = None) -> bool:
        """Review and respond to an approval request"""
        if request_id not in self.approval_requests:
            return False
        
        response = ApprovalResponse(
            request_id=request_id,
            status=status,
            approved_by=reviewer,
            approved_at=int(time.time()) if status == ApprovalStatus.APPROVED else None,
            rejection_reason=rejection_reason,
            notes=notes
        )
        
        self.approval_responses[request_id] = response
        
        # Update approved nodes set
        if status == ApprovalStatus.APPROVED:
            request = self.approval_requests[request_id]
            self.approved_nodes.add(request.node_id)
        elif status in [ApprovalStatus.REJECTED, ApprovalStatus.REVOKED]:
            request = self.approval_requests[request_id]
            self.approved_nodes.discard(request.node_id)
        
        return True
    
    def is_approved(self, node_id: str, approval_type: ApprovalType) -> bool:
        """Check if a node is approved for a specific type of access"""
        if approval_type == ApprovalType.HEAD_NODE:
            return node_id in self.approved_nodes
        return False  # Other types would have different checks
    
    def get_pending_requests(self) -> List[ApprovalRequest]:
        """Get list of pending approval requests"""
        pending = []
        for req_id, req in self.approval_requests.items():
            response = self.approval_responses.get(req_id)
            if not response or response.status == ApprovalStatus.PENDING:
                pending.append(req)
        return pending


# Global instance of the approval system
smilyai_approval_system = SmilyaiApprovalSystem()