from fb_tools.config import CfgFileOptionAction
from fb_tools.errors import FbAppError
from fb_tools.collections import FrozenCIStringSet, CIStringSet, CIDict
+from fb_tools.xlate import format_list
-from .config import LDAPMigrationConfiguration
+from .config import LDAPMigrationConfiguration, DEFAULT_ENV
-__version__ = '0.12.0'
+__version__ = '0.13.0'
LOG = logging.getLogger(__name__)
CFG_BASENAME = 'ldap-migration.ini'
self.lap = 0
self.total_count = 0
self.do_aci = False
+ self.init_only = False
self.struct_entries = []
self.all_entries = []
self._cfg_dir = self.base_dir.joinpath('etc')
self._cfg_file = self.cfg_dir.joinpath(CFG_BASENAME)
default_cfg_file = copy.copy(self.cfg_file)
+ envs = format_list(LDAPMigrationConfiguration.environments, do_repr=True, style='or')
app_group = self.arg_parser.add_argument_group('Migration options')
+ app_group.add_argument(
+ '-E', '--env', '--environment', metavar='ENVIRONMENT', dest='env',
+ required=True, choices=LDAPMigrationConfiguration.environments, default=DEFAULT_ENV,
+ help=("The target environment. Valid values are {envs}. "
+ "Default: {env!r}.").format(envs=envs, env=DEFAULT_ENV),
+ )
+
app_group.add_argument(
'-T', '--timeout', dest='timeout', type=int, metavar='SECONDS',
action=LimitedIntegerOptionAction,
help="Configuration file (default: {!r})".format(str(default_cfg_file))
)
+ app_group.add_argument(
+ '-I', '--init-only', action="store_true", dest="init_only",
+ help=("Only perform initialization steps, like connecting to the LDAP "
+ "servers and discovering target schema, don't execute the migration."),
+ )
+
# -------------------------------------------------------------------------
def _get_log_formatter(self, is_term=True):
self._cfg_file = self.args.cfg_file
self._cfg_dir = self.cfg_file.parent
+ if self.args.init_only:
+ self.init_only = True
+
self.config = LDAPMigrationConfiguration(
appname=self.appname, verbose=self.verbose, base_dir=self.base_dir,
- config_file=self.cfg_file)
+ config_file=self.cfg_file, environment=self.args.env)
self.config.read()
if self.config.verbose > self.verbose:
self.connect_source()
self.connect_target()
self.discover_target_schema()
- self.get_all_dns()
- self.get_structural_dns()
- self.migrate_entries()
- self.detailled_summary()
+ if not self.init_only:
+ self.get_all_dns()
+ self.get_structural_dns()
+ self.migrate_entries()
+ self.detailled_summary()
finally:
self.disconnect()
- self.summary()
+ if not self.init_only:
+ self.summary()
LOG.info("Ending {a!r}.".format(
a=self.appname, v=self.version))
# Standard module
import logging
import re
+
from pathlib import Path
# Third party modules
from fb_tools.common import to_bool
from fb_tools.config import ConfigError, BaseConfiguration
+from fb_tools.xlate import format_list
__version__ = '0.3.1'
LOG = logging.getLogger(__name__)
-
+DEFAULT_ENV = 'prd'
# =============================================================================
class LDAPMigrationConfigError(ConfigError):
default_tgt_server = 'ldap2.pixelpark.com'
default_tgt_use_ssl = True
default_tgt_port = 636
- default_tgt_bind_dn = 'cn=admin,o=isp'
+ default_tgt_bind_dn = 'cn=admin'
default_suffix = 'o=isp'
default_timeout = 20
max_timeout = 3600
default_wait_after_write = 0.1
+ environments = ('dev', 'test', 'prd')
+
re_bind_dn = re.compile(r'^\s*bind[_-]?dn\s*$', re.IGNORECASE)
re_bind_pw = re.compile(r'^\s*bind[_-]?(?:pw|passwd|passsword)\s*$', re.IGNORECASE)
# -------------------------------------------------------------------------
def __init__(
self, appname=None, verbose=0, version=__version__, base_dir=None,
- xlations_definitions_base=None,
+ xlations_definitions_base=None, environment=DEFAULT_ENV,
encoding=None, config_dir=None, config_file=None, initialized=False):
+ if environment not in self.environments:
+ envs = format_list(self.environments, do_repr=True, style='or')
+ msg = ("Given environment {env!r} is invalid. A valid environment "
+ "must be one of {envs}.").format(
+ env=environment, envs=envs)
+ raise ValueError(msg)
+
+ self.environment = environment
+
self.src_server = self.default_src_server
self.src_use_ssl = self.default_src_use_ssl
self._src_port = self.default_src_port
self._eval_config_source(config, section_name)
return
+ tgt_section = 'target.' + self.environment
+ if section_name.lower() == tgt_section:
+ self._eval_config_target(config, section_name)
+ return
+
+ # Overruling target definitions
if section_name.lower() == 'target' or section_name.lower() == 'tgt':
self._eval_config_target(config, section_name)
return