Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions keepercommander/commands/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,21 @@ def register_commands(commands, aliases, command_info):
service_commands(commands)
service_command_info(aliases, command_info)

if sys.version_info.major == 3 and sys.version_info.minor >= 8:
from . import discoveryrotation
discoveryrotation.register_commands(commands)
discoveryrotation.register_command_info(aliases, command_info)
toggle_pam_legacy_commands(legacy=False)


def register_pam_legacy_commands():
from . import discoveryrotation_v1
discoveryrotation_v1.register_commands(commands)
discoveryrotation_v1.register_command_info(aliases, command_info)
def toggle_pam_legacy_commands(legacy: bool):
if sys.version_info.major > 3 or (sys.version_info.major == 3 and sys.version_info.minor >= 8):
from . import discoveryrotation
from . import discoveryrotation_v1
if legacy is True:
discoveryrotation_v1.register_commands(commands)
discoveryrotation_v1.register_command_info(aliases, command_info)
else:
discoveryrotation.register_commands(commands)
discoveryrotation.register_command_info(aliases, command_info)
else:
logging.debug('pam commands require Python 3.8 or newer')


def register_enterprise_commands(commands, aliases, command_info):
Expand Down
33 changes: 23 additions & 10 deletions keepercommander/commands/discoveryrotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from keeper_secrets_manager_core.utils import url_safe_str_to_bytes

from .base import (Command, GroupCommand, user_choice, dump_report_data, report_output_parser, field_to_title,
FolderMixin, RecordMixin, register_pam_legacy_commands)
FolderMixin, RecordMixin, toggle_pam_legacy_commands)
from .folder import FolderMoveCommand
from .ksm import KSMCommand
from .pam import gateway_helper, router_helper
Expand Down Expand Up @@ -102,7 +102,7 @@ def __init__(self):
self.register_command('action', GatewayActionCommand(), 'Execute action on the Gateway', 'a')
self.register_command('tunnel', PAMTunnelCommand(), 'Manage Tunnels', 't')
self.register_command('split', PAMSplitCommand(), 'Split credentials from legacy PAM Machine', 's')
self.register_command('legacy', PAMLegacyCommand(), 'Switch to legacy PAM commands')
self.register_command('legacy', PAMLegacyCommand(), 'Toggle PAM Legacy commands: ON/OFF')
self.register_command('connection', PAMConnectionCommand(), 'Manage Connections', 'n')
self.register_command('rbi', PAMRbiCommand(), 'Manage Remote Browser Isolation', 'b')
self.register_command('project', PAMProjectCommand(), 'PAM Project Import/Export', 'p')
Expand Down Expand Up @@ -231,13 +231,26 @@ def __init__(self):


class PAMLegacyCommand(Command):
parser = argparse.ArgumentParser(prog='pam legacy', description="Switch to using obsolete PAM commands")
parser = argparse.ArgumentParser(prog='pam legacy', description="Toggle PAM Legacy mode: ON/OFF - PAM Legacy commands are obsolete")
parser.add_argument('--status', '-s', required=False, dest='status', action='store_true', help='Show the current status - Legacy mode: ON/OFF')

def get_parser(self):
return PAMLegacyCommand.parser

def execute(self, params, **kwargs):
register_pam_legacy_commands()
from .base import commands
status = kwargs.get('status') or False
pamc = commands.get("pam")
# Legacy mode is missing: connection, split, rbi, project (tunnel - commented out)
conn = pamc.subcommands.get("connection") if pamc and pamc.subcommands else None
legacy = False if conn and isinstance(conn, PAMConnectionCommand) else True
if status:
if legacy:
print("PAM Legacy mode: ON")
else:
print ("PAM Legacy mode: OFF")
return
toggle_pam_legacy_commands(not legacy)


class PAMCmdListJobs(Command):
Expand Down Expand Up @@ -1611,7 +1624,7 @@ def print_root_rotation_setting(params, is_verbose=False, format_type='table'):
azure_group.add_argument('--subscription_id', dest='subscription_id', action='store',
help='Subscription Id')
azure_group.add_argument('--tenant-id', dest='tenant_id', action='store', help='Tenant Id')
azure_group.add_argument('--resource-group', dest='resource_group', action='append', help='Resource Group')
azure_group.add_argument('--resource-group', dest='resource_groups', action='append', help='Resource Group')


class PamConfigurationEditMixin(RecordEditMixin):
Expand Down Expand Up @@ -1643,7 +1656,7 @@ def parse_pam_configuration(self, params, record, **kwargs):
record.fields.append(field)

if len(field.value) == 0:
field.value.append(dict())
field.value.append({})
value = field.value[0]

gateway_uid = None # type: Optional[str]
Expand Down Expand Up @@ -1720,7 +1733,7 @@ def parse_properties(self, params, record, **kwargs): # type: (KeeperParams, va
if schedule:
extra_properties.append(f'schedule.defaultRotationSchedule={schedule}')
else:
extra_properties.append(f'schedule.defaultRotationSchedule=On-Demand')
extra_properties.append('schedule.defaultRotationSchedule=On-Demand')

if record.record_type == 'pamNetworkConfiguration':
network_id = kwargs.get('network_id')
Expand Down Expand Up @@ -1759,9 +1772,9 @@ def parse_properties(self, params, record, **kwargs): # type: (KeeperParams, va
tenant_id = kwargs.get('tenant_id')
if tenant_id:
extra_properties.append(f'secret.tenantId={tenant_id}')
resource_group = kwargs.get('resource_group')
if isinstance(resource_group, list) and len(resource_group) > 0:
rg = '\n'.join(resource_group)
resource_groups = kwargs.get('resource_groups')
if isinstance(resource_groups, list) and len(resource_groups) > 0:
rg = '\n'.join(resource_groups)
extra_properties.append(f'multiline.resourceGroups={rg}')
if extra_properties:
self.assign_typed_fields(record, [RecordEditMixin.parse_field(x) for x in extra_properties])
Expand Down
4 changes: 3 additions & 1 deletion keepercommander/commands/discoveryrotation_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from keeper_secrets_manager_core.utils import url_safe_str_to_bytes

from .base import Command, GroupCommand, user_choice, dump_report_data, report_output_parser, field_to_title, FolderMixin
from .discoveryrotation import PAMLegacyCommand
from .folder import FolderMoveCommand
from .ksm import KSMCommand
from .pam import gateway_helper, router_helper
Expand Down Expand Up @@ -49,7 +50,7 @@ def register_commands(commands):


def register_command_info(_, command_info):
command_info['pam'] = 'Manage PAM Components.'
command_info['pam'] = 'Manage PAM Components (Legacy).'


class PAMControllerCommand(GroupCommand):
Expand All @@ -60,6 +61,7 @@ def __init__(self):
self.register_command('config', PAMConfigurationsCommand(), 'Manage PAM Configurations', 'c')
self.register_command('rotation', PAMRotationCommand(), 'Manage Rotations', 'r')
self.register_command('action', GatewayActionCommand(), 'Execute action on the Gateway', 'a')
self.register_command('legacy', PAMLegacyCommand(), 'Toggle PAM Legacy commands: ON/OFF')
# self.register_command('tunnel', PAMTunnelCommand(), 'Manage Tunnels', 't')


Expand Down
31 changes: 23 additions & 8 deletions keepercommander/commands/pam_import/edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ def process_pam_config(self, params, project: dict) -> dict:
if pce.az_client_secret: args["client_secret"] = pce.az_client_secret
if pce.az_subscription_id: args["subscription_id"] = pce.az_subscription_id
if pce.az_tenant_id: args["tenant_id"] = pce.az_tenant_id
if pce.az_resource_groups: args["resource_group"] = pce.az_resource_groups
if pce.az_resource_groups: args["resource_groups"] = pce.az_resource_groups

if pce.default_rotation_schedule: args["default_schedule"] = pce.default_rotation_schedule

Expand Down Expand Up @@ -1681,23 +1681,38 @@ def _initialize(self):
self.attachments = None # PamAttachmentsObject

# common settings (local, aws, az)
self.pam_resources = {} # {"controllerUid": "", "controllerUid": ""} - "resourceRef": unused/legacy
self.pam_resources = {} # {"folderUid": "", "controllerUid": ""} - "resourceRef": unused/legacy

# Local environment
self.network_id: str = "" # text:networkId prefix for naming resources during discovery
self.network_cidr: str = "" # text:networkCIDR network CIDR used for discovery
self.network_id: str = "" # required, text:networkId prefix for naming resources during discovery
self.network_cidr: str = "" # required, text:networkCIDR network CIDR used for discovery
# AWS environment
self.aws_id: str = "" # required, text:awsId
self.aws_access_key_id: str = "" # secret:accessKeyId
self.aws_secret_access_key: str = "" # secret:accessSecretKey
self.aws_region_names: List[str] = [] # multiline:regionNames
self.aws_id: str = "" # required, text:awsId
self.aws_access_key_id: str = "" # required, secret:accessKeyId
self.aws_secret_access_key: str = "" # required, secret:accessSecretKey
self.aws_region_names: List[str] = [] # optional, multiline:regionNames
# Azure environment
self.az_entra_id: str = "" # required, text:azureId
self.az_client_id: str = "" # required, secret:clientId
self.az_client_secret: str = "" # required, secret:clientSecret
self.az_subscription_id: str = "" # required, secret:subscriptionId
self.az_tenant_id: str = "" # required, secret:tenantId
self.az_resource_groups: List[str] = [] # optional, multiline:resourceGroups
# Domain environment: pamDomainConfiguration
self.dom_domain_id: str = '' # required, text:pamDomainId
self.dom_hostname: str = '' # required, pamHostname:
self.dom_port: str = '' # required, pamHostname:
self.dom_use_ssl: bool = False # required, checkbox:useSSL
self.dom_scan_dc_cidr: bool = False # optional, checkbox:scanDCCIDR
self.dom_network_cidr: str = '' # optional, multiline:networkCIDR
# Oracle Cloud Infrastructure (OCI) environment: pamOciConfiguration
# NB! OCI settings subject to change:
self.oci_oci_id: str = '' # required, text:pamOciId
self.oci_admin_oci_id: str = '' # required, secret:adminOcid
self.oci_admin_public_key: str = '' # required, secret:adminPublicKey
self.oci_admin_private_key: str = '' # required, secret:adminPrivateKey
self.oci_tenancy_oci: str = '' # required, text:tenancyOci
self.oci_region_oci: str = '' # required, text:regionOci

def __init__(self, environment_type:str, settings:dict, controller_uid:str, folder_uid:str) -> None:
self._initialize()
Expand Down
6 changes: 3 additions & 3 deletions keepercommander/keeper_dag/vertex.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,14 +520,14 @@ def belongs_to(self, vertex: DAGVertex, edge_type: EdgeType, content: Optional[A
:return:
"""

self.debug(f"connect {self.uid} to {vertex.uid} with edge type {edge_type.value}", level=1)
self.dag.logger.debug(f"connect {self.uid} to {vertex.uid} with edge type {edge_type.value}", level=1)

if vertex is None:
raise ValueError("Vertex is blank.")
if self.uid == self.dag.uid and not (edge_type == EdgeType.DATA or edge_type == EdgeType.DELETION):
if from_load is False:
raise DAGIllegalEdgeException(f"Cannot create edge to self for edge type {edge_type}.")
self.dag.debug(f"vertex {self.uid} , the root vertex, "
self.dag.logger.debug(f"vertex {self.uid} , the root vertex, "
f"attempted to create '{edge_type.value}' edge to self, skipping.")
return

Expand All @@ -538,7 +538,7 @@ def belongs_to(self, vertex: DAGVertex, edge_type: EdgeType, content: Optional[A
if self.uid == vertex.uid and not (edge_type == EdgeType.DATA or edge_type == EdgeType.DELETION):
if from_load is False:
raise DAGIllegalEdgeException(f"Cannot create edge to self for edge type {edge_type}.")
self.dag.debug(f"vertex {self.uid} attempted to make '{edge_type.value}' to self, skipping.")
self.dag.logger.debug(f"vertex {self.uid} attempted to make '{edge_type.value}' to self, skipping.")
return

# Figure out what version of the edge we are.
Expand Down