示例#1
0
 def take_action(self, parsed_args):
     secrets_basedir = self.app.secrets_basedir
     if parsed_args.alias is not None:
         if len(parsed_args.env) != 1:
             raise RuntimeError(
                 '[-] --alias requires one source environment')
         se = SecretsEnvironment(
             environment=parsed_args.alias,
             secrets_basedir=secrets_basedir,
             create_root=parsed_args.force,
         )
         se.environment_create(
             source=parsed_args.env[0],
             alias=True
         )
         if se.environment_exists():
             self.logger.info(
                 "[+] environment '%s' aliased to '%s'",
                 parsed_args.alias,
                 parsed_args.env[0]
             )
         else:
             raise RuntimeError('[-] creating environment failed')
     else:
         # Default to app environment identifier
         if len(parsed_args.env) == 0:
             parsed_args.env = list(self.app.environment)
         for environment in parsed_args.env:
             se = SecretsEnvironment(
                 environment=environment,
                 secrets_basedir=secrets_basedir,
                 create_root=True,
             )
             se.environment_create(source=parsed_args.clone_from)
             self.logger.info(
                 "[+] environment '%s' (%s) created",
                 environment,
                 se.get_environment_path()
             )
             if parsed_args.clone_from:
                 se.read_secrets(from_descriptions=True)
                 se.write_secrets()
示例#2
0
 def take_action(self, parsed_args):
     if (len(parsed_args.arg) == 0 and not parsed_args.undefined
             and not parsed_args.from_options):
         raise RuntimeError('[-] no secrets specified to be set')
     se = self.app.secrets
     se.requires_environment()
     se.read_secrets_and_descriptions()
     # TODO(dittrich): Use Variable map like this elsewhere
     variables = dict(se.Variable)
     types = dict(se.Type)
     from_env = None
     if parsed_args.from_environment is not None:
         from_env = SecretsEnvironment(
             environment=parsed_args.from_environment)
         from_env.read_secrets()
         variables = dict(from_env._secrets.Variable)
         types = dict(from_env._secrets.Type)
     args = (list(variables.keys())
             if len(parsed_args.arg) == 0 else parsed_args.arg)
     if parsed_args.undefined and len(variables) > 0:
         # Downselect to just those currently undefined
         args = [k for k, v in variables.items() if v in [None, '']]
     if len(args) == 0:
         raise RuntimeError('[-] no secrets identified to be set')
     for arg in args:
         k, v, k_type = None, None, None
         if parsed_args.from_options:
             k, v, k_type = (arg, se.get_default_value(arg), types.get(arg))
             # Don't set from options if the type is generable
             if is_generable(k_type):
                 continue
         elif '=' not in arg:
             # No value was specified with the argument
             k = arg
             k_type = se.secrets.get_type(k)
             if k_type is None:
                 self.logger.info("[-] no description for '%s'", k)
                 raise RuntimeError(
                     f"[-] variable '{k}' has no description")
             if from_env is not None:
                 # Getting value from same var, different environment
                 v = from_env.get_secret(k, allow_none=True)
             else:
                 # Try to prompt user for value
                 if (k_type == 'boolean' and k not in se.Options):
                     # Default options for boolean type
                     se.Options[k] = BOOLEAN_OPTIONS
                 k_options = se.get_options(k)
                 if (k_options != '*' and k in se.Options):
                     # Attempt to select from list. Options will look like
                     # 'a,b' or 'a,b,*', or 'a,*'.
                     old_v = se.get_secret(k, allow_none=True)
                     v = prompt_options_list(
                         options=k_options.split(','),
                         default=(None if old_v in ['', None] else old_v),
                         prompt=se.get_prompt(k))
                     if v is None:
                         # User cancelled selection.
                         break
                     v = v if v not in ['', '*'] else None
                 # Ask user for value
                 if v is None:
                     v = prompt_string(prompt=se.get_prompt(k), default="")
                 v = v if v != '' else None
         else:  # ('=' in arg)
             # Assignment syntax found (a=b)
             lhs, rhs = arg.split('=')
             k_type = se.get_type(lhs)
             if k_type is None:
                 self.logger.info("[-] no description for '%s'", lhs)
                 raise RuntimeError(
                     f"[-] variable '{lhs}' has no description")
             k = lhs
             if from_env is not None:
                 # Get value from different var in different environment
                 v = from_env.get_secret(rhs, allow_none=True)
                 self.logger.info(
                     "[+] getting value from '%s' in environment '%s'", rhs,
                     str(from_env))
             else:
                 # Value was specified in arg
                 v = rhs
             if v is not None:
                 # Is the value indirectly referenced?
                 if v.startswith('@'):
                     if v[1] == '~':
                         _path = os.path.expanduser(v[1:])
                     else:
                         _path = v[1:]
                     with open(_path, 'r') as f:
                         v = f.read().strip()
                 elif v.startswith('!'):
                     # >> Issue: [B603:subprocess_without_shell_equals_true] subprocess call - check for execution of untrusted input.  # noqa
                     #    Severity: Low   Confidence: High
                     #    Location: psec/secrets.py:641
                     p = run(v[1:].split(),
                             stdout=PIPE,
                             stderr=PIPE,
                             shell=False)
                     v = p.stdout.decode('UTF-8').strip()
         # After all that, did we get a value?
         if v is None:
             self.logger.info("[-] could not obtain value for '%s'", k)
         else:
             self.logger.debug("[+] setting variable '%s'", k)
             se.set_secret(k, v)