def _promote(self): repeat = True parameters: List[Dict] = [] while repeat: namespace = Input.input("Please input a namespace prefix to promote:" f" (i.e. {self.context.defaults.service_ns}/foo/): ", completer=self._config_completer) if not self._utils.is_valid_input(namespace, "namespace", notify=False): continue try: parameters: List[Dict] = self._source_ssm.get_all_parameters([namespace]) if not parameters and self._source_ssm.get_parameter(namespace): parameters, latest_version = self._source_ssm.get_parameter_details(namespace) parameters = list(parameters) if parameters: repeat = False else: self._out.warn("\nNo parameters found. Try again.\n") except ClientError as e: print(f"{self.c.fg_rd}ERROR: >> {e}{self.c.rs}") continue self._out.notify(f'\nFound [[{len(parameters)}]] parameter{"s" if len(parameters) > 1 else ""} to migrate.\n') assumable_roles = self.context.defaults.assumable_roles matching_roles = list(set([x for x in assumable_roles if x.role == self.config_context.role])) valid_envs = set([x.run_env.env for x in matching_roles]) valid_envs.remove(self.run_env.env) # Remove current env, we can't promote from dev -> dev next_env = Input.select(f'Please select the destination environment.', valid_options=list(valid_envs)) matching_role = [role for role in matching_roles if role.run_env == RunEnv(env=next_env)][0] env: GlobalEnvironment = GlobalEnvironment(role=matching_role, region=self.config_context.defaults.region) dest_ssm = SsmDao(self._session_mgr.get_session(env, prompt=False).client('ssm')) for param in parameters: if 'KeyId' in param: self._out.print(f"Skipping param: [[{param['Name']}]]. It is encrypted and cannot be migrated.") else: promote_it = Input.y_n_input(f"Would you like to promote: {param['Name']}?", default_yes=True) if promote_it: val = self._source_ssm.get_parameter(param['Name']) description = param.get('Description', "") dest_ssm.set_parameter(param['Name'], val, description, SSM_STRING) self._out.success(f"Successfully promoted [[{param['Name']}]] to [[{next_env}]].\r\n")
def _restore_param(self) -> None: """ Allow the user to query a parameter store entry from dynamo, so we can query + restore it, if desired. """ table_entries = [] ps_name = prompt(f"Please input PS key to restore: ", completer=self._config_completer) if self._is_replication_destination(ps_name): repl_conf = self._repl.get_config_repl(ps_name) self._print_cannot_restore_msg(repl_conf) exit(0) self._out.notify( f"\n\nAttempting to retrieve all restorable values of [[{ps_name}]]" ) items: List[RestoreConfig] = self._audit.get_parameter_restore_details( ps_name) if len(items) == 0: self._out.warn( "No restorable values were found for this parameter.") return for i, item in enumerate(items): date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(item.ps_time / 1000)) # we need to decrypt the value, if encrypted, in order to show it to the user if item.ps_key_id: item.ps_value = self._kms.decrypt_with_context( item.ps_value, {"PARAMETER_ARN": self.get_parameter_arn(item.ps_name)}, ) table_entries.append([i, date, item.ps_value, item.ps_user]) self._out.print( tabulate( table_entries, headers=["Item #", "Time Created", "Value", "User"], tablefmt="grid", numalign="center", stralign="left", )) valid_options = [f'{x}' for x in range(0, len(items))] choice = int( Input.select("Select an item number to restore: ", valid_options=valid_options)) item = items[choice] if items[choice] else None restore = Input.y_n_input( f"Are you sure you want to restore item #{choice} and have it be the latest version? ", default_yes=False) if not restore: self._utils.warn_exit("Restore aborted.") key_id = None if item.ps_type == "String" else item.ps_key_id try: self._ssm.set_parameter(item.ps_name, item.ps_value, item.ps_description, item.ps_type, key_id=key_id) current_value = self._ssm.get_parameter(item.ps_name) if current_value == item.ps_value: self._out.success("Restore was successful") else: self._out.error( "Latest version in parameter store doesn't match what we restored." ) self._out.print( f"Current value: [[{current_value}]]. Expected value: [[{item.ps_value}]]" ) except ClientError as e: self._client_exception_msg(item, e)
def login_sandbox(self): """ If user provides --role flag, skip role & env selection for a smoother user experience. """ EnvironmentValidator(self._defaults).validate_environment_variables() Utils.wipe_vaults() or Utils.wipe_defaults( ) or Utils.wipe_config_cache() self._out.print( f"{self.c.fg_bl}Logging you into the Figgy Sandbox environment.{self.c.rs}" ) user = Input.input("Please input a user name: ", min_length=2) colors = Input.select_enable_colors() # Prompt user for role if --role not provided if commands.role not in self.context.options: role = Input.select("\n\nPlease select a role to impersonate: ", valid_options=SANDBOX_ROLES) else: role = self.context.role.role self._utils.validate( role in SANDBOX_ROLES, f"Provided role: >>>`{role}`<<< is not a valid sandbox role." f" Please choose from {SANDBOX_ROLES}") params = {'role': role, 'user': user} result = requests.get(GET_SANDBOX_CREDS_URL, params=params) if result.status_code != 200: self._utils.error_exit( "Unable to get temporary credentials from the Figgy sandbox. If this problem " f"persists please notify us on our GITHUB: {FIGGY_GITHUB}") data = result.json() response = SandboxLoginResponse(**data) self._aws_cfg.write_credentials( access_key=response.AWS_ACCESS_KEY_ID, secret_key=response.AWS_SECRET_ACCESS_KEY, token=response.AWS_SESSION_TOKEN, region=FIGGY_SANDBOX_REGION, profile_name=FIGGY_SANDBOX_PROFILE) defaults = CLIDefaults.sandbox(user=user, role=role, colors=colors) self._setup.save_defaults(defaults) run_env = RunEnv( env='dev', account_id=SANDBOX_DEV_ACCOUNT_ID) if self.context.role else None config_mgr = ConfigManager.figgy() config_mgr.set(Config.Section.Bastion.PROFILE, FIGGY_SANDBOX_PROFILE) defaults = self._setup.configure_extras(defaults) defaults = self._setup.configure_roles(current_defaults=defaults, role=Role(role=role), run_env=run_env) defaults = self._setup.configure_figgy_defaults(defaults) self._setup.save_defaults(defaults) self._out.success( f"\nLogin successful. Your sandbox session will last for [[1 hour]]." ) self._out.print( f"\nIf your session expires, you may rerun `{CLI_NAME} login sandbox` to get another sandbox session. " f"\nAll previous figgy sessions have been disabled, you'll need to run {CLI_NAME} " f"--configure to leave the sandbox.")