Skip to content

Commit 48f800b

Browse files
authored
ARK-600: ISP Session Monitoring / Activites Support (#6)
* ARK-600: ISP Session Monitoring / Activites Support * ARK-600: ISP Session Monitoring / Activites Support * ARK-600: ISP Session Monitoring / Activites Support
1 parent c9ce376 commit 48f800b

25 files changed

+724
-2
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ test:
6262

6363
package:
6464
@echo Package sdk
65-
poetry build
65+
poetry build --format wheel
66+
poetry run scripts/wheel_editor.sh dist/ark_sdk_python*x86_64.whl
6667

6768
publish-test:
6869
@echo Release to test.pypi.org and create git tag

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ CyberArk's Official SDK and CLI for different services operations
2121
- [x] DPA SSO Service
2222
- [x] DPA K8S Service
2323
- [x] DPA DB Service
24+
- [x] Session Monitoring Service
2425
- [x] All services contains CRUD and Statistics per respective service
2526
- [x] Ready to use SDK in Python
2627
- [x] CLI and SDK Examples

ark_sdk_python/ark_api.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,15 @@ def dpa_k8s(self) -> "ArkDPAK8SService":
175175
from ark_sdk_python.services.dpa.k8s import ArkDPAK8SService
176176

177177
return cast(ArkDPAK8SService, self.service(ArkDPAK8SService))
178+
179+
@property
180+
def sm(self) -> "ArkSMService":
181+
"""
182+
Returns the SM service if the appropriate authenticators were given
183+
184+
Returns:
185+
ArkSMService: _description_
186+
"""
187+
from ark_sdk_python.services.sm import ArkSMService
188+
189+
return cast(ArkSMService, self.service(ArkSMService))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from typing import Any, List
22

33
from ark_sdk_python.models.actions.services.ark_dpa_exec_action_consts import DPA_ACTIONS
4+
from ark_sdk_python.models.actions.services.ark_sm_exec_action_consts import SM_ACTIONS
45

56
SUPPORTED_SERVICE_ACTIONS: List[Any] = [
67
DPA_ACTIONS,
8+
SM_ACTIONS,
79
]
810

911
__all__ = [
1012
'DPA_ACTIONS',
13+
'SM_ACTIONS',
1114
'SUPPORTED_SERVICE_ACTIONS',
1215
]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Any, Dict, Final, Optional, Type
2+
3+
from ark_sdk_python.models import ArkModel
4+
from ark_sdk_python.models.actions.ark_service_action_definition import ArkServiceActionDefinition
5+
from ark_sdk_python.models.services.sm import ArkSMGetSession, ArkSMGetSessionActivities, ArkSMSessionActivitiesFilter, ArkSMSessionsFilter
6+
7+
# Session Monitoring Definitions
8+
SM_ACTION_TO_SCHEMA_MAP: Final[Dict[str, Optional[Type[ArkModel]]]] = {
9+
'list-sessions': None,
10+
'count-sessions': None,
11+
'list-sessions-by': ArkSMSessionsFilter,
12+
'count-sessions-by': ArkSMSessionsFilter,
13+
'session': ArkSMGetSession,
14+
'list-session-activities': ArkSMGetSessionActivities,
15+
'count-session-activities': ArkSMGetSessionActivities,
16+
'list-session-activities-by': ArkSMSessionActivitiesFilter,
17+
'count-session-activities-by': ArkSMSessionActivitiesFilter,
18+
'sessions-stats': None,
19+
}
20+
SM_ACTION_DEFAULTS_MAP: Final[Dict[str, Dict[str, Any]]] = {}
21+
22+
# Service Actions Definition
23+
SM_ACTIONS: Final[ArkServiceActionDefinition] = ArkServiceActionDefinition(
24+
action_name='sm',
25+
schemas=SM_ACTION_TO_SCHEMA_MAP,
26+
defaults=SM_ACTION_DEFAULTS_MAP,
27+
)

ark_sdk_python/models/common/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from ark_sdk_python.models.common.ark_access_method import ArkAccessMethod
2+
from ark_sdk_python.models.common.ark_application_code import ArkApplicationCode
13
from ark_sdk_python.models.common.ark_async_request_settings import ArkAsyncRequestSettings
24
from ark_sdk_python.models.common.ark_async_status import ArkAsyncStatus
35
from ark_sdk_python.models.common.ark_async_task import ArkAsyncTask
@@ -29,9 +31,11 @@
2931
'ArkWorkspaceType',
3032
'ArkNetworkEntityType',
3133
'ArkConnectorType',
34+
'ArkApplicationCode',
3235
'ArkProtocolType',
3336
'VALID_DATE_REGEX',
3437
'VALID_LOGIN_MAX_LENGTH',
3538
'VALID_LOGIN_NAME_REGEX',
3639
'ArkConnectionMethod',
40+
'ArkAccessMethod',
3741
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from enum import Enum
2+
3+
4+
class ArkAccessMethod(str, Enum):
5+
VAULTED = 'Vaulted'
6+
JIT = 'JIT'
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from enum import Enum
2+
3+
4+
class ArkApplicationCode(str, Enum):
5+
DPA = 'DPA'
6+
CSM = 'CSM'
7+
PAM = 'PAM'
8+
DAP = 'DAP'
9+
ITI = 'ITI'
10+
UBA = 'UBA'
11+
ADM = 'ADM'
12+
USR = 'USR'
13+
AUD = 'AUD'
14+
ALR = 'ALR'
15+
CEM = 'CEM'
16+
EPM = 'EPM'
17+
SCA = 'SCA'
18+
SHSM = 'SHSM'
19+
CLO = 'CLO'
20+
CMS = 'CMS'

ark_sdk_python/models/common/ark_protocol_type.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ class ArkProtocolType(str, MultiValueEnum):
99
CLI = 'cli', 'CLI'
1010
CONSOLE = 'console', 'Console'
1111
HTTPS = 'https', 'HTTPS'
12+
K8S = 'K8S', 'k8s'
13+
DB = 'Database', 'database', 'DATABASE'
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from ark_sdk_python.models.services.sm.ark_sm_get_session import ArkSMGetSession
2+
from ark_sdk_python.models.services.sm.ark_sm_get_session_activities import ArkSMGetSessionActivities
3+
from ark_sdk_python.models.services.sm.ark_sm_protocol_type_serializer import serialize_sm_protocol_type
4+
from ark_sdk_python.models.services.sm.ark_sm_session import ArkSMSession, ArkSMSessions, ArkSMSessionStatus
5+
from ark_sdk_python.models.services.sm.ark_sm_session_activity import ArkSMSessionActivities, ArkSMSessionActivity
6+
from ark_sdk_python.models.services.sm.ark_sm_session_activity_filter import ArkSMSessionActivitiesFilter
7+
from ark_sdk_python.models.services.sm.ark_sm_sessions_filter import ArkSMSessionsFilter
8+
from ark_sdk_python.models.services.sm.ark_sm_sessions_stats import ArkSMSessionsStats
9+
from ark_sdk_python.models.services.sm.ark_sm_workspace_type_serializer import serialize_sm_workspace_type
10+
11+
__all__ = [
12+
'ArkSMSession',
13+
'ArkSMSessions',
14+
'ArkSMSessionStatus',
15+
'ArkSMSessionsFilter',
16+
'ArkSMSessionsStats',
17+
'ArkSMGetSession',
18+
'ArkSMGetSessionActivities',
19+
'ArkSMSessionActivity',
20+
'ArkSMSessionActivities',
21+
'ArkSMSessionActivitiesFilter',
22+
'serialize_sm_workspace_type',
23+
'serialize_sm_protocol_type',
24+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from pydantic import Field
2+
3+
from ark_sdk_python.models import ArkModel
4+
5+
6+
class ArkSMGetSession(ArkModel):
7+
session_id: str = Field(description='Session id to get')
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from pydantic import Field
2+
3+
from ark_sdk_python.models import ArkModel
4+
5+
6+
class ArkSMGetSessionActivities(ArkModel):
7+
session_id: str = Field(description='Session id to get the activities for')
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from ark_sdk_python.models import ArkException
2+
from ark_sdk_python.models.common import ArkProtocolType
3+
4+
5+
def serialize_sm_protocol_type(protocol_type: ArkProtocolType) -> str:
6+
if isinstance(protocol_type, str):
7+
protocol_type = ArkProtocolType(protocol_type)
8+
if protocol_type == ArkProtocolType.SSH:
9+
return 'SSH'
10+
elif protocol_type == ArkProtocolType.RDP:
11+
return 'RDP'
12+
elif protocol_type == ArkProtocolType.CLI:
13+
return 'CLI'
14+
elif protocol_type == ArkProtocolType.CONSOLE:
15+
return 'Console'
16+
elif protocol_type == ArkProtocolType.HTTPS:
17+
return 'HTTPS'
18+
elif protocol_type == ArkProtocolType.K8S:
19+
return 'K8S'
20+
elif protocol_type == ArkProtocolType.DB:
21+
return 'Database'
22+
raise ArkException('Invalid SM Protocol Type')
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from datetime import datetime, timedelta
2+
from enum import Enum
3+
from typing import Any, Dict, List, Optional
4+
5+
from pydantic import Field
6+
7+
from ark_sdk_python.models import ArkCamelizedModel
8+
from ark_sdk_python.models.common import ArkAccessMethod, ArkApplicationCode, ArkProtocolType, ArkWorkspaceType
9+
10+
11+
class ArkSMSessionStatus(str, Enum):
12+
ACTIVE = 'Active'
13+
ENDED = 'Ended'
14+
FAILED = 'Failed'
15+
16+
17+
class ArkSMSession(ArkCamelizedModel):
18+
tenant_id: Optional[str] = Field(description='Tenant id of the session')
19+
session_id: str = Field(description='Session id')
20+
session_status: Optional[ArkSMSessionStatus] = Field(description='Status of the session')
21+
session_duration: Optional[timedelta] = Field(description='Duration of the session in seconds')
22+
end_reason: Optional[str] = Field(description='End reason for the session')
23+
error_code: Optional[str] = Field(description='Error code for the session')
24+
application_code: Optional[ArkApplicationCode] = Field(description='Application code of the session')
25+
access_method: Optional[ArkAccessMethod] = Field(description='Access method of the session')
26+
start_time: Optional[datetime] = Field(description='Start time of the session')
27+
end_time: Optional[datetime] = Field(description='End time of the session')
28+
user: Optional[str] = Field(description='Username of the session')
29+
source: Optional[str] = Field(description='Source of the session (Usually Ip)')
30+
target: Optional[str] = Field(description='Target of the session (Usually Ip/Dns)')
31+
target_username: Optional[str] = Field(description='Target username of the session')
32+
protocol: Optional[ArkProtocolType] = Field(description='Connection protocol of the session')
33+
platform: Optional[ArkWorkspaceType] = Field(description='Connection platform of the session')
34+
custom_data: Optional[Dict[str, Any]] = Field(description='Custom data of the session')
35+
36+
37+
class ArkSMSessions(ArkCamelizedModel):
38+
sessions: List[ArkSMSession] = Field(description='List of the sessions')
39+
filtered_count: int = Field(description='How many sessions were filtered')
40+
returned_count: int = Field(description='How many sessions were returned')
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from datetime import datetime
2+
from typing import List, Optional
3+
4+
from pydantic import Field
5+
6+
from ark_sdk_python.models import ArkCamelizedModel
7+
from ark_sdk_python.models.common import ArkApplicationCode
8+
9+
10+
class ArkSMSessionActivity(ArkCamelizedModel):
11+
uuid: str = Field(description='ID of the audit')
12+
tenant_id: str = Field(description='Tenant id of the audit')
13+
timestamp: datetime = Field(description='Time of the audit')
14+
username: str = Field(description='Username of the audit')
15+
application_code: ArkApplicationCode = Field(description='Application code of the audit')
16+
action: str = Field(description='Action performed for the audit')
17+
user_id: str = Field(description='Id of the user who performed the audit')
18+
source: str = Field(description='Source of the audit')
19+
action_type: str = Field(description='Type of action for the audit')
20+
audit_code: Optional[str] = Field(description='Audit code of the audit')
21+
command: Optional[str] = Field(description='Command performed as part of the audit')
22+
target: Optional[str] = Field(description='Target of the audit')
23+
service_name: Optional[str] = Field(description='Service name of the audit')
24+
session_id: Optional[str] = Field(description='Session id of the audit if related to a session')
25+
message: Optional[str] = Field(description='Message of the audit')
26+
27+
28+
class ArkSMSessionActivities(ArkCamelizedModel):
29+
activities: List[ArkSMSessionActivity] = Field(description='List of the session activities')
30+
filtered_count: int = Field(description='How many session activities were filtered')
31+
returned_count: int = Field(description='How many session activities were returned')
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pydantic import Field
2+
3+
from ark_sdk_python.models import ArkCamelizedModel
4+
5+
6+
class ArkSMSessionActivitiesFilter(ArkCamelizedModel):
7+
session_id: str = Field(description='Session id to get')
8+
command_contains: str = Field(description='String which the command contains')
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from pydantic import Field, constr
2+
3+
from ark_sdk_python.models import ArkCamelizedModel
4+
5+
6+
class ArkSMSessionsFilter(ArkCamelizedModel):
7+
search: constr(max_length=4096) = Field(
8+
description='Free text query to search sessions by. For example: "startTime GE 2023-11-18T06:53:30Z AND status IN Failed,Ended AND endReason STARTSWITH Err008"'
9+
)
10+
11+
class Config:
12+
schema_extra = {
13+
'examples': [
14+
{
15+
'search': 'duration LE 01:00:00',
16+
},
17+
{
18+
'search': 'startTime GE 2023-11-18T06:53:30Z',
19+
},
20+
{
21+
'search': 'status IN Failed,Ended AND endReason STARTSWITH Err008',
22+
},
23+
{
24+
'search': 'command STARTSWITH ls',
25+
},
26+
{
27+
'search': 'protocol IN SSH,RDP',
28+
},
29+
]
30+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from typing import Dict
2+
3+
from pydantic import Field, validator
4+
5+
from ark_sdk_python.models import ArkModel
6+
from ark_sdk_python.models.common import ArkApplicationCode, ArkProtocolType, ArkWorkspaceType
7+
from ark_sdk_python.models.services.sm.ark_sm_session import ArkSMSessionStatus
8+
9+
10+
class ArkSMSessionsStats(ArkModel):
11+
sessions_count: int = Field(description='Sessions count in the last 30 days')
12+
sessions_count_per_application_code: Dict[ArkApplicationCode, int] = Field(description='Sessions count per application code')
13+
sessions_count_per_platform: Dict[ArkWorkspaceType, int] = Field(description='Sessions count per platform')
14+
sessions_count_per_status: Dict[ArkSMSessionStatus, int] = Field(description='Sessions count per status')
15+
sessions_count_per_protocol: Dict[ArkProtocolType, int] = Field(description='Sessions count per protocol')
16+
sessions_failure_count: int = Field(description='Sessions count with failures')
17+
18+
# pylint: disable=no-self-use,no-self-argument
19+
@validator('sessions_count_per_platform')
20+
def validate_sessions_count_per_platform(cls, val):
21+
for platform in val.keys():
22+
if ArkWorkspaceType(platform) not in [
23+
ArkWorkspaceType.AWS,
24+
ArkWorkspaceType.AZURE,
25+
ArkWorkspaceType.GCP,
26+
ArkWorkspaceType.ONPREM,
27+
ArkWorkspaceType.UNKNOWN,
28+
]:
29+
raise ValueError('Invalid Platform / Workspace Type')
30+
return val
31+
32+
# pylint: disable=no-self-use,no-self-argument
33+
@validator('sessions_count_per_protocol')
34+
def validate_sessions_count_per_protocol(cls, val):
35+
for protocol in val.keys():
36+
if ArkProtocolType(protocol) not in [
37+
ArkProtocolType.SSH,
38+
ArkProtocolType.RDP,
39+
ArkProtocolType.CLI,
40+
ArkProtocolType.CONSOLE,
41+
ArkProtocolType.HTTPS,
42+
ArkProtocolType.K8S,
43+
ArkProtocolType.DB,
44+
]:
45+
raise ValueError('Invalid Protocol Type')
46+
return val
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from ark_sdk_python.models import ArkException
2+
from ark_sdk_python.models.common import ArkWorkspaceType
3+
4+
5+
def serialize_sm_workspace_type(ws_type: ArkWorkspaceType):
6+
if isinstance(ws_type, str):
7+
ws_type = ArkWorkspaceType(ws_type)
8+
if ws_type == ArkWorkspaceType.AWS:
9+
return 'AWS'
10+
elif ws_type == ArkWorkspaceType.AZURE:
11+
return 'Azure'
12+
elif ws_type == ArkWorkspaceType.ONPREM:
13+
return 'OnPrem'
14+
elif ws_type == ArkWorkspaceType.GCP:
15+
return 'GCP'
16+
elif ws_type == ArkWorkspaceType.UNKNOWN:
17+
return 'Unknown'
18+
raise ArkException('Invalid SM Workspace Type')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from ark_sdk_python.services.sm.ark_sm_service import ArkSMService
2+
3+
__all__ = ['ArkSMService']

0 commit comments

Comments
 (0)