Пример #1
0
 def get_parser(self, prog_name):
     parser = super().get_parser(prog_name)
     how = parser.add_mutually_exclusive_group(required=False)
     default_environment = get_default_environment()
     how.add_argument(
         '-A', '--alias',
         action='store',
         dest='alias',
         default=None,
         help='Environment to alias'
     )
     how.add_argument(
         '-C', '--clone-from',
         action='store',
         dest='clone_from',
         default=None,
         help='Environment directory to clone from'
     )
     parser.add_argument(
         '--force',
         action='store_true',
         dest='force',
         default=False,
         help='Create secrets base directory'
     )
     parser.add_argument(
         'env',
         nargs='*',
         default=[default_environment]
     )
     return parser
Пример #2
0
 def take_action(self, parsed_args):
     default_env = get_default_environment()
     columns = (['Environment', 'Default'])
     if parsed_args.aliasing:
         columns.append('AliasFor')
     data = list()
     for env_path in get_environment_paths(
             basedir=self.app.secrets_basedir):  # noqa
         if is_valid_environment(
                 env_path,
                 self.app_args.verbose_level,
         ):
             is_default = ("Yes" if env_path.name == default_env else "No")
             if not parsed_args.aliasing:
                 item = (env_path.name, is_default)
             else:
                 try:
                     alias_for = os.path.basename(os.readlink(env_path))
                 except OSError:
                     alias_for = ''
                 item = (env_path.name, is_default, alias_for)
             data.append(item)
     if len(data) == 0:
         sys.exit(1)
     return columns, data
Пример #3
0
 def get_parser(self, prog_name):
     parser = super().get_parser(prog_name)
     default_environment = get_default_environment()
     parser.add_argument('environment',
                         nargs='?',
                         default=default_environment)
     return parser
Пример #4
0
 def take_action(self, parsed_args):
     if parsed_args.unset:
         if parsed_args.environment is not None:
             raise RuntimeError("[-] '--unset' does not take an argument")
         if clear_saved_default_environment():
             self.logger.info('[+] explicit default environment unset')
         else:
             self.logger.info('[+] no default environment was set')
     elif parsed_args.set:
         # If it is not possible to interactively ask for environment,
         # just raise an exception.
         if (parsed_args.environment is None
                 and not (stdin.isatty() and 'Bullet' in globals())):
             raise RuntimeError('[-] no environment specified')
         # Otherwise, let's prompt for an environment for better UX!
         if parsed_args.environment is not None:
             choice = parsed_args.environment
         else:
             basedir = self.app.secrets.get_secrets_basedir()
             environments = [
                 env_path.name
                 for env_path in get_environment_paths(basedir=basedir)
             ]
             choices = ['<CANCEL>'] + sorted(environments)
             cli = Bullet(prompt="\nChose a new default environment:",
                          choices=choices,
                          indent=0,
                          align=2,
                          margin=1,
                          shift=0,
                          bullet="→",
                          pad_right=5)
             choice = cli.launch()
             # Having second thoughts, eh?
             if choice == "<CANCEL>":
                 self.logger.info('[-] cancelled setting default')
         if save_default_environment(choice):
             self.logger.info(
                 "[+] default environment explicitly set to '%s'", choice)
     elif parsed_args.environment is not None:
         print(parsed_args.environment)
     else:
         # No environment specified; show current setting.
         env_string = get_saved_default_environment()
         if env_string is not None:
             if self.app_args.verbose_level > 1:
                 self.logger.info(
                     "[+] default environment explicitly set to '%s'",
                     env_string)
         else:
             # No explicit saved default.
             env_string = get_default_environment()
             if self.app_args.verbose_level > 1:
                 self.logger.info(
                     "[+] default environment is implicitly '%s'",
                     env_string)
         print(env_string)
Пример #5
0
 def test_get_default_environment_default_file(self):
     tmp_dir = '/tmp'
     new_env_file = get_local_default_file(cwd=tmp_dir)
     self.assertEqual(new_env_file,
                      Path(tmp_dir) / '.python_secrets_environment')
     with open(new_env_file, 'w') as f_out:
         f_out.write(TESTENV)
     default_env = get_default_environment(cwd=tmp_dir)  # noqa
     os.unlink(new_env_file)
     self.assertEqual(default_env, TESTENV)
Пример #6
0
 def __init__(
     self,
     environment=None,
     secrets_basedir=None,
     secrets_file=None,
     create_root=False,
     defer_loading=False,
     export_env_vars=False,
     preserve_existing=False,
     env_var_prefix=None,
     source=None,
     verbose_level=1,
 ):
     """
     Initialize secrets environment object.
     """
     if secrets_file and secrets_basedir:
         raise RuntimeError(
             "[-] 'secrets_file' and 'secrets_basedir' are mutually "
             "exclusive when initializing a SecretsEnvironment()")
     self._environment = (get_default_environment()
                          if environment is None else environment)
     if secrets_basedir is None:
         secrets_basedir = get_default_secrets_basedir()
     try:
         is_secrets_basedir(basedir=secrets_basedir, raise_exception=True)
         self._secrets_basedir = Path(secrets_basedir)
     except BasedirNotFoundError:
         if create_root:
             self._secrets_basedir = secrets_basedir_create(
                 basedir=secrets_basedir)
         else:
             raise
     if secrets_file is not None:
         self._secrets_file = Path(secrets_file)
         if len(self._secrets_file.parts) < 3:
             # This might not exactly be true in all cases, but I don't
             # have time to run down all possible use cases (or put in
             # all necessary checks) at the moment.
             raise RuntimeError(
                 '[-] the path to a secrets file should have '
                 f"at least 3 components ('{self._secrets_file}')")
         if not self._secrets_file.exists():
             raise RuntimeError(
                 f"[-] the specified secrets file '{secrets_file}' "
                 'does not exist')
         if self._environment != self._secrets_file.parts[-2]:
             raise RuntimeError(
                 f"[-] environment name '{environment}' does not "
                 f"match secrets file path '{secrets_file}'")
         if Path(secrets_basedir) not in self._secrets_file.parents:
             raise RuntimeError(
                 f"[-] base directory '{secrets_basedir}' does not "
                 f"match secrets file path '{secrets_file}'")
         self.secrets_basedir = self._secrets_file.parents[1]
     else:
         self._secrets_file = self._secrets_basedir / self._environment / SECRETS_FILE  # noqa
     self._secrets_descriptions = self._secrets_file.parent / SECRETS_DESCRIPTIONS_DIR  # noqa
     self._verbose_level = verbose_level
     self.export_env_vars = export_env_vars
     self.preserve_existing = preserve_existing
     # When exporting environment variables, include one that specifies the
     # environment from which these variables were derived. This also works
     # around a limitation in Ansible where the current working directory
     # from which "ansible" was run. (The D2 lookup_plugin/python_secrets.py
     # script needs to communicate this back to python_secrets in order for
     # it's .python_secrets_environment file to be used to identify the
     # proper environment.)
     if self.export_env_vars is True:
         os.environ['D2_ENVIRONMENT'] = self._environment
         # Deprecating this variable name:
         os.environ['PYTHON_SECRETS_ENVIRONMENT'] = self._environment
     self.env_var_prefix = env_var_prefix
     # Secrets attribute maps; anything else throws exception
     for a in SECRET_ATTRIBUTES:
         setattr(self, a, OrderedDict())
     if source is not None:
         self.clone_from(source)
         self.read_secrets_descriptions()
     self._secrets = OrderedDict()
     self._descriptions = OrderedDict()
     self._changed = False
Пример #7
0
# Local imports
from psec import __version__
from psec.secrets_environment import SecretsEnvironment
from psec.utils import (  # noqa
    bell, ensure_secrets_basedir, get_default_environment,
    get_default_secrets_basedir, permissions_check, show_current_value, umask,
    DEFAULT_UMASK, Timer,
)

# Commands that do not need secrets environments.
DOES_NOT_NEED_SECRETS = ['complete', 'help', 'init', 'utils']
# Use syslog for logging?
# TODO(dittrich) Make this configurable, since it can fail on Mac OS X
SYSLOG = False

DEFAULT_ENVIRONMENT = get_default_environment()
DEFAULT_BASEDIR = get_default_secrets_basedir()


class PythonSecretsApp(App):
    """Python secrets application class."""
    def __init__(self):
        super().__init__(
            description=__doc__.strip(),
            version=__version__,
            command_manager=CommandManager(namespace='psec'),
            deferred_help=True,
        )
        self.secrets = None
        self.environment = None
        self.secrets_basedir = None
Пример #8
0
 def test_get_default_environment_no_default_file(self):
     cwd = os.getcwd()
     self.assertEqual(get_default_environment(cwd=cwd),
                      os.path.basename(cwd))