def get_repo_head_hash(quiet=False): try: headhash = misc.to_unicode(call(GitDefault.GetHeadHash), locale.getpreferredencoding()) return headhash.replace(os.linesep, u'') except subprocess.CalledProcessError as ex: # Git returned with an error code log.error( u'Git local repository does not have HEAD info: "{0}".'.format( ex)) if quiet: return None else: raise EBSCliException( DevToolsMessage.GitHeadNotExist.format(ex.message)) except (OSError, IOError) as ex: log.error(u'Failed to call git, because "{0}".'.format(ex)) if quiet: return None else: # Cannot find or run script if ex.errno == FileErrorConstant.FileNotFoundErrorCode: log.error(u'Cannot find Git executable "git".') raise EBSCliException( DevToolsMessage.GitCommandError.format(ex.message))
def _validate_change(self, parameter_pool, eb_client, app_name, env_name, option_settings, option_remove, template_spec): response = eb_client.validate_configuration_settings(app_name, option_settings, environment_name = env_name, option_remove = option_remove, template_specification = template_spec) warning_count = 0 error_count = 0 for message in response.result: if misc.string_equal_ignore_case(message.severity, ValidationSeverity.SeverityError): error_count = error_count + 1 else: warning_count = warning_count + 1 prompt.error(ValidationMessage.ValidateSettingError.format\ (message.severity, message.namespace, message.option_name, message.message)) if error_count > 0: log.info('Validating configuration setting failed. Abort command.') raise EBSCliException() elif warning_count > 0: if parameter_pool.get_value(ParameterName.Force) == ServiceDefault.ENABLED: pass elif not TerminalBase.ask_confirmation(UpdateEnvironmentOptionSettingOpMessage.Continue): log.info('User cancelled command.') raise EBSCliException() else: log.info('Validating configuration setting passed.')
def get_working_branch(quiet=False): try: result = misc.to_unicode(call(GitDefault.GetBranch), locale.getpreferredencoding()) branches = result.splitlines() if len(branches) == 0: return None, 0 else: head_re = re.compile(GitDefault.HeadRe, re.UNICODE) for branch in branches: if head_re.match(branch): return branch.split(u' ')[1], len(branches) except subprocess.CalledProcessError as ex: # Git returned with an error code log.error(u'Git local repository is not set up: "{0}".'.format(ex)) if quiet: return None, 0 else: raise EBSCliException( DevToolsMessage.GitRepoNotExist.format(ex.message)) except (OSError, IOError) as ex: log.error(u'Failed to call git, because "{0}".'.format(ex)) if quiet: return None, 0 else: # Cannot find or run script if ex.errno == FileErrorConstant.FileNotFoundErrorCode: log.error(u'Cannot find Git executable "git".') raise EBSCliException( DevToolsMessage.GitCommandError.format(ex.message))
def git_aws_push(push_only=False, quiet=False): output = prompt.info if quiet else prompt.result cmd = DevToolsDefault.AwsCreateAppVersion if push_only else DevToolsDefault.AwsPush try: output( misc.to_unicode(call(cmd, quiet=quiet), locale.getpreferredencoding())) return True except subprocess.CalledProcessError as ex: # Git returned with an error code log.error(u'Failed to push local HEAD to EB: "{0}".'.format(ex)) if quiet: return False else: raise EBSCliException(DevToolsMessage.PushFail.format(ex.message)) except (OSError, IOError) as ex: log.error(u'Failed to call git, because "{0}".'.format(ex)) if quiet: return False else: # Cannot find or run script if ex.errno == FileErrorConstant.FileNotFoundErrorCode: log.error(u'Cannot find Git executable "git".') raise EBSCliException( DevToolsMessage.GitCommandError.format(ex.message))
def trim_aws_credential_file(location, param_list, quiet = False): try: log.info(u'Trimming AWS credential file: "{0}"'.format(location)) parser = NoSectionConfigParser() try: parser.read(location) except IOError as ex: return # File not exists for name in param_list: parser.remove_option(name) parser.write(location) log.info(u'Finished trimming AWS credential file.') # Set access permission set_access_permission(location, False) log.info(u'Set AWS credential file access permission.') except BaseException as ex: log.error(u'Failed to trim AWS credential file at "{0}", because: "{1}"'.\ format(location, ex)) msg = CredentialFileErrorMessage.WriteError.format(location) prompt.error(msg) if not quiet: raise EBSCliException(msg) else: return False # if failed, just skip
def ask_master_password(cls, parameter_pool): for _ in range(0, RdsDefault.PasswordMismatchThreshold): password = cls.ask_value(parameter_pool, PName.RdsMasterPassword, no_echo=True) if password is None: return else: if not ParameterValidator.validate_alphanumeric( password, RdsDefault.PasswordMinSize, RdsDefault.PasswordMaxSize): prompt.error(RdsTerminalMessage.PasswordWrongFormat) continue confirm = cls.line_input( RdsTerminalMessage.PasswordConfirmation, can_return_none=False, no_echo=True) if confirm != password: prompt.error(RdsTerminalMessage.PasswordNotMatch) else: parameter_pool.put( Parameter(PName.RdsMasterPassword, password, PSource.Terminal), True) return else: prompt.error(RdsTerminalMessage.PasswordMatchFailure) raise EBSCliException()
def call(command, quiet=True): ''' Call external process. command is a list of command line arguments including name of external process and arguments. ''' if isinstance(command, basestring): command_line = shlex.split(command) elif isinstance(command, list): command_line = command else: raise EBSCliException(u'Parameter must be instance of list or string.') log.debug(u'Running external commands "{0}".'.\ format(misc.collection_to_string(command_line))) # Using OS native code page command_line = map(lambda x: x.encode(locale.getpreferredencoding()), command_line) args = {'args': command_line} if misc.is_os_windows(): # TODO: set shell to True will allow Windows translate "git" to "git.cmd", # but might introduce other issues. args['shell'] = True if quiet: args['stderr'] = subprocess.STDOUT return misc.to_unicode(subprocess.check_output(**args), False, locale.getpreferredencoding())
def execute(self, parameter_pool): location = EbLocalDir.Path + os.path.sep + EbConfigFile.Name try: config_file.load_eb_config_file(location, parameter_pool, False) if config_file.check_access_permission(location) is False: message = ConfigFileErrorMessage.PermissionError.format(EbConfigFile.Name) log.info(message) prompt.error(message) #Post processing if not parameter_pool.has(ParameterName.RdsSnippetUrl)\ and parameter_pool.has(ParameterName.Region): region = parameter_pool.get_value(ParameterName.Region, False) parameter_pool.put(Parameter(ParameterName.RdsSnippetUrl, RdsDefault.get_snippet_url(region), ParameterSource.ConfigFile)) except EBConfigFileNotExistError: log.error(u'Configuration file "{0}" not exist.'.format(EbConfigFile.Name)) prompt.error(ConfigFileMessage.CannotFind.format\ (EbConfigFile.Name, CommandType.INIT.lower())) raise EBSCliException() except BaseException as ex: log.error(u'Encountered error when load configuration file "{0}", becuase "{1}".'.\ format(EbConfigFile.Name, ex)) prompt.error(ConfigFileMessage.CorrectionSuggestion. format(location,CommandType.INIT.lower())) raise ret_result = OperationResult(self, None, None, None) return ret_result
def execute(self, parameter_pool): eb_client = self._get_eb_client(parameter_pool) app_name = parameter_pool.get_value(ParameterName.ApplicationName, False) env_name = parameter_pool.get_value(ParameterName.EnvironmentName, False) max_records = parameter_pool.get_value(ParameterName.SubCommand) try: max_records = int(max_records[0]) if len( max_records) > 0 else ServiceDefault.EVENT_DEFAULT_NUM except ValueError: raise EBSCliException( GetEnvironmentEventsOpMessage.NotValidNumber.format( max_records[0])) response = eb_client.describe_events(app_name, env_name, max_records=max_records) if len(response.result) > 0: for event in response.result: msg = u'{0}\t{1}\t{2}'.format(event.event_date, event.severity, event.message) prompt.plain(msg) ret_result = OperationResult(self, response.request_id, None, response.result) return ret_result
def single_choice(cls, choice_list, title=None, message=None, can_return_none=False): if choice_list and not isinstance(choice_list, list): raise EBSCliException(u'Invalid parameter type.') if message is None: message = TerminalMessage.SingleChoice if title is not None: print title for index, choice in enumerate(choice_list): print u'{0}) {1}'.format(index + 1, choice) select = -1 while select not in range(1, len(choice_list) + 1): select = cls.line_input( u'{0} ({1} to {2}): '.format(message, 1, len(choice_list)), True) if select is None and can_return_none: return None # No input from customer, return None try: select = int(select) except: select = -1 return select - 1
def read_aws_credential_file(location, parameter_pool, func_matrix, source, quiet=False): try: env_name = parameter_pool.get_value(ParameterName.EnvironmentName) \ if parameter_pool.has(ParameterName.EnvironmentName) else u'' log.info(u'Reading AWS credential from file: "{0}"'.format(location)) parser = NoSectionConfigParser() parser.read(location) for name, from_file_func in func_matrix: if name == ParameterName.RdsMasterPassword: key_name = rds_utils.password_key_name(env_name) else: key_name = AwsCredentialFileDefault.KeyName[name] if parser.has_option(key_name): value = parser.get(key_name) value = from_file_func( value) if from_file_func is not None else value parameter_pool.put(Parameter(name, value, source)) log.info(u'Finished reading AWS credential from file.') except BaseException as ex: log.error(u'Failed to retrieve AWS credential from file "{0}", because: "{1}"'.\ format(location, ex)) if not quiet: msg = CredentialFileErrorMessage.ReadError.format(location) prompt.error(msg) raise EBSCliException(msg) else: return False # if failed, just skip
def execute(self, parameter_pool): command = parameter_pool.get_value(PName.Command, False) self._probe_rds_change(parameter_pool, command) if parameter_pool.get_value(PName.Force) == ServiceDefault.ENABLED \ or TerminalBase.ask_confirmation(AskConfirmationOpMessage.CommandConfirmation[command]): ret_result = OperationResult(self, None, None, None) return ret_result else: log.info(u'User cancelled command.') raise EBSCliException()
def execute(self, parameter_pool): # Update parameter self._update_timeout_thresholds(parameter_pool) # Checking parameters required_params = self._operation_queue.required_parameters missing_params = required_params - parameter_pool.parameter_names if len(missing_params) > 0: raise EBSCliException(u'Missing required parameter. "{0}"'.format(missing_params)) log.debug(u'Finished gathering required parameter') ret_result = OperationResult(self, None, None, None) return ret_result
def write_aws_credential_file(location, parameter_pool, func_matrix, quiet=False): try: log.info(u'Writing AWS credential to file: "{0}"'.format(location)) parser = NoSectionConfigParser() try: parser.read(location) except IOError as ex: pass # No existing file for branch, name, to_file_func in func_matrix: if branch: value = parameter_pool.get_value(ParameterName.Branches, False)[branch][name] env_name = parameter_pool.get_value(ParameterName.Branches, False)[branch]\ [ParameterName.EnvironmentName] else: value = parameter_pool.get_value(name, False) env_name = parameter_pool.get_value( ParameterName.EnvironmentName, False) if to_file_func: value = to_file_func(value) if name == ParameterName.RdsMasterPassword: key_name = rds_utils.password_key_name(env_name) else: key_name = AwsCredentialFileDefault.KeyName[name] parser.set(key_name, value) parser.write(location) log.info(u'Finished writing AWS credential to file.') # Set access permission set_access_permission(location, False) log.info(u'Set AWS credential file access permission.') except BaseException as ex: log.error(u'Failed to update AWS credential file at "{0}", because: "{1}"'.\ format(location, ex)) msg = CredentialFileErrorMessage.WriteError.format(location) prompt.error(msg) if not quiet: raise EBSCliException(msg) else: return False # if failed, just skip
def ask_profile_creation(cls, parameter_pool): try: iam_client = api_wrapper.create_iam_client(parameter_pool) original_value = parameter_pool.get_value(PName.InstanceProfileName) if original_value is None or len(original_value) < 1: append_message = TerminalMessage.CurrentValue.format(IamTerminalMessage.CreateProfile) else: append_message = TerminalMessage.CurrentValue.format(original_value) print(IamTerminalMessage.ProfileNameSelect.format(append_message)) profiles = iam_client.list_instance_profiles().result sorted_profiles = cls._sort_instance_profile_by_time(profiles) profile_list = [IamTerminalMessage.CreateProfile]; for i in range(0, min(len(sorted_profiles), TerminalConstant.IamProfileListNumber)): profile_list.append(sorted_profiles[i].name) profile_list.append(IamTerminalMessage.OtherProfile) profile_index = cls.single_choice(choice_list = profile_list, can_return_none = True) if profile_index == 0: # Create profile instance from scratch value = None elif profile_index == len(profile_list) - 1: # Name not in list value = cls._ask_for_specific_profile(parameter_pool, sorted_profiles) else: value = profile_list[profile_index] if profile_index is not None else original_value if value is None or len(value) < 1: value = cls._create_default_profile(iam_client, parameter_pool) except AccessDeniedException as ex: prompt.error(IamTerminalMessage.AccessDeniedMessage.format(ex.message)) if cls.ask_confirmation(IamTerminalMessage.ContinueWithoutRole): value = u'' else: raise EBSCliException() profile = Parameter(PName.InstanceProfileName, value, PSource.Terminal) parameter_pool.put(profile, True)
def _call(self, command, *params): ''' Call external process. command is a list of command line arguments including name of external process. params will be appended at the tail of command. ''' if not isinstance(command, list): raise EBSCliException('Parameter must be instance of list.') command_line = command for param in params: command_line.append(param) log.debug('Running external commands "{0}".'.\ format(misc.collection_to_string(command_line))) if misc.is_os_windows(): # TODO: set shell to True will allow Windows translate "git" to "git.cmd", # but might introduce other issues. # Using Windows native code page command_line = [ x.encode(locale.getpreferredencoding()) for x in command_line ] return _subprocess.check_output(command_line, shell=True) else: return _subprocess.check_output(command_line)