def get_availability_domains(ctx, word_before_cursor, bottom_toolbar, sub_string=""): compartment_id = cli_util.get_tenancy_from_config(ctx) completions = [] try: identity_client = cli_util.build_client("identity", "identity", ctx) response = identity_client.list_availability_domains( compartment_id=compartment_id) if len(response.data) == 0: bottom_toolbar.set_toolbar_text( get_error_message("no_items_found"), is_error=True) else: items = response.data for item in items: if not sub_string or sub_string.lower() in item.name.lower(): completions.append( Completion(item.name, -len(word_before_cursor), display=item.name)) except Exception: bottom_toolbar.set_toolbar_text( get_error_message("resource_search_failed"), is_error=True, ) return completions
def get_compute_images(ctx, word_before_cursor, bottom_toolbar, sub_string=""): compartment_id = cli_util.get_tenancy_from_config(ctx) completions = [] try: compute_client = cli_util.build_client("core", "compute", ctx) kwargs = {"lifecycle_state": "AVAILABLE"} response = compute_client.list_images(compartment_id=compartment_id, **kwargs) items = response.data for item in items: if not sub_string or sub_string.lower() in item.display_name.lower( ): completions.append( Completion(item.id, -len(word_before_cursor), display=item.display_name)) if not completions: bottom_toolbar.set_toolbar_text( get_error_message("no_items_found"), is_error=True) except Exception: bottom_toolbar.set_toolbar_text( get_error_message("resource_search_failed"), is_error=True) return completions
def _clear_history(event) -> None: buffer = event.current_buffer # Clear history when user presses [F7] shortcut keys try: # Clear Command History cli_interactive_history = buffer.history cli_interactive_history.delete_history_file() # Clear Cache buffer.reset() # Notify User except Exception as e: kwargs["toolbar"].set_toolbar_text( get_error_message("try_again"), is_error=True, ) else: kwargs["toolbar"].set_toolbar_text( get_error_message("history_clear"), is_error=False, )
def _enter_key(event) -> None: # the main purpose of this function is, pressing enter chooses the option then pressing enter again executes the # command buffer = event.current_buffer missing_required_param = all_required_param_selected( buffer.text, kwargs["completer"].list_of_required_params ) if ( not buffer.text or not buffer.complete_state ): # If in the beginning or no menu(meaning menu is already chosen) if not missing_required_param: named_commands.accept_line(event) else: kwargs["toolbar"].set_toolbar_text( get_error_message( "missing_required_params", str(missing_required_param) ), is_error=True, ) else: # Copy the current selection and append it a new document document_with_selection, _ = buffer.document.cut_selection() buffer.reset() buffer.document = document_with_selection
def get_oci_resources(ctx, param_name, word_before_cursor, bottom_toolbar, sub_string=""): resource_search_client = cli_util.build_client("resource_search", "resource_search", ctx) if param_name == "--availability-domain": completions = get_availability_domains(ctx, word_before_cursor, bottom_toolbar, sub_string) return completions if param_name == "--shape": completions = get_compute_shapes(ctx, word_before_cursor, bottom_toolbar, sub_string) return completions if param_name == "--image-id": completions = get_compute_images(ctx, word_before_cursor, bottom_toolbar, sub_string) return completions # If the condition below is True, It means the parameter is not a resource parameter or the resource is not # supported by the Query Search API, so just allow the user to enter a value if (param_name not in parameter_resource_mapping or parameter_resource_mapping[param_name]["resource_type"] not in supported_resource_types): return [] completions = [] parameter_resource = parameter_resource_mapping[param_name] search_details = dict() search_details["type"] = "Structured" if ( not sub_string or len(sub_string) < 3 ): # Since QRS API filter for substring len 3+, load all and the filter will happen in the client side search_details["query"] = ( "query " + parameter_resource["resource_type"] + " resources" ) # Example is "query Compartment resources" else: search_details["query"] = ( "query " + parameter_resource["resource_type"] + " resources where displayName =~ '" + sub_string + "'" ) # Example is "query Compartment resources matching 'cli_compartmen'" try: response = resource_search_client.search_resources( search_details=search_details, limit=500) if len(response.data.items) == 0: bottom_toolbar.set_toolbar_text( get_error_message("no_items_found"), is_error=True) else: items = response.data.items for item in items: # Filter locally if the substring is smalled than 3 characters if (sub_string and len(sub_string) < 3 and sub_string.lower() not in item.display_name.lower()): continue completions.append( Completion( item.identifier if parameter_resource["field_to_use"] == "identifier" else item.display_name, -len(word_before_cursor), display=item.display_name, )) except Exception: bottom_toolbar.set_toolbar_text( get_error_message("resource_search_failed"), is_error=True, ) return completions
def validate_incorrect_input(completions, word_before_cursor, bottom_toolbar): # This function checks if the user types incorrect text in the terminal if not completions: error_message = get_error_message("invalid_input", word_before_cursor) bottom_toolbar.set_toolbar_text(error_message, is_error=True)
def get_completions(self, document, _): is_leaf_command_met = False completions = [] self.list_of_required_params.clear( ) # remove required param from previous command word_before_cursor = document.get_word_before_cursor(WORD=True) tokens = shlex.split(handle_invalid_chars(document.text)) # Since not all the services are loaded in the beginning, so root_subcommands reads from service_mapping only_at_top_level = True top_level_commands = self.top_level_commands service_subcommands = [] token_check = tokens[:] if document.text.endswith(" ") else tokens[:-1] remaining_command_tokens = tokens[:] command = None already_chosen_parameters = set() parameter = None param_value = "" # this will save parameter value between quotes ( " " or ' ' ) with space for token_index, token in enumerate(token_check): # add parameters to the list so they will be excluded from the list given to the user if token.startswith("-"): already_chosen_parameters.update( self.list_all_parameter_names(command, token)) parameter = token remaining_command_tokens.remove(token) continue elif token_index == 0 and token in top_level_commands: # Load the service and all its subcommands. for example "oci compute instance", load the compute service dynamic_loader.load_service(token) oci_subcommands = getattr(self.ctx.command, "commands", {}) command = oci_subcommands[token] service_subcommands = getattr(command, "commands", {}) service_subcommands = collections.OrderedDict( sorted(service_subcommands.items())) only_at_top_level = False elif service_subcommands and token in service_subcommands: command = service_subcommands[token] service_subcommands = getattr(command, "commands", {}) if not service_subcommands: is_leaf_command_met = True service_subcommands = collections.OrderedDict( sorted(service_subcommands.items())) elif ( not parameter ): # Not valid command, subcommand or parameter and not a value for a parameter self.bottom_toolbar.set_toolbar_text(get_error_message( "invalid_input", token), is_error=True) return completions elif parameter and (token.startswith('"') or token.startswith("'") or param_value): if token.startswith('"') or token.startswith("'"): param_value += token elif param_value: param_value += token if is_matching_quotes(param_value): parameter = None param_value = "" else: parameter = None remaining_command_tokens.remove(token) remaing_sub_string = ("" if len(remaining_command_tokens) == 0 else remaining_command_tokens[0]) # If at top level, read top level commands and show them in the list if only_at_top_level: completions = self.append_top_level_command_completions( word_before_cursor, remaing_sub_string) validate_incorrect_input(completions, word_before_cursor, self.bottom_toolbar) return completions # If the last token is a command, then show the sub commands if len(service_subcommands) > 0: completions = self.append_command_completions( service_subcommands, word_before_cursor, remaing_sub_string) validate_incorrect_input(completions, word_before_cursor, self.bottom_toolbar) return completions if is_leaf_command_met: self.get_list_of_req_param(command) if not parameter: completions = self.append_parameter_completions( command, word_before_cursor, "", already_chosen_parameters, remaing_sub_string, ) validate_incorrect_input(completions, word_before_cursor, self.bottom_toolbar) return completions # if the last token is a parameter, then check if a list of resources need to be provided or the parameter # does not need a value like --all if check_param_is_flag(command, parameter): completions = self.append_parameter_completions( command, word_before_cursor, "", already_chosen_parameters, remaing_sub_string, ) else: completions = get_oci_resources( self.ctx, parameter, word_before_cursor, self.bottom_toolbar, remaing_sub_string, ) return completions