diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 0000000..5173a48 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1 @@ +- Guillaume Archambault ([Gu1llaum-3](https://github.com/Gu1llaum-3)) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6330e95 --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ +Voici le contenu complet du fichier `README.md` sous format code : + +```markdown +# SSH Manager (sshm) + +SSH Manager (sshm) is a bash script that simplifies and automates the management of SSH hosts through the SSH configuration file (`~/.ssh/config`). It provides functionalities to list, connect, view, add, edit, and delete SSH host configurations, as well as to check the availability of hosts using pings. + +## Features + +- List all SSH hosts in the configuration file. +- Connect to an SSH host by number or name. +- View the configuration details of a specific SSH host. +- Add a new SSH host configuration. +- Edit an existing SSH host configuration. +- Delete an SSH host configuration. +- Check the availability of an SSH host using ping. + +## Requirements + +- Bash +- SSH +- awk +- sed +- ping + +## Installation + +1. Clone the repository: + + ```bash + git clone https://github.com/yourusername/sshm.git + cd sshm + ``` + +2. Make the script executable: + + ```bash + chmod +x sshm + ``` + +3. Move the script to a directory in your PATH, for example: + + ```bash + sudo mv sshm /usr/local/bin/ + ``` + +## Usage + +### List SSH Hosts + +```bash +sshm list +``` + +### Connect to an SSH Host + +```bash +sshm connect +``` + +### View SSH Host Configuration + +```bash +sshm view +``` + +### Add a New SSH Host Configuration + +```bash +sshm add +``` + +The script will prompt you to enter the host details. + +### Edit an Existing SSH Host Configuration + +```bash +sshm edit +``` + +The script will prompt you to enter the new details for the host. + +### Delete an SSH Host Configuration + +```bash +sshm delete +``` + +### Check SSH Host Availability + +```bash +sshm ping +``` + +## Example + +### Adding a New SSH Host + +```bash +sshm add +``` + +You will be prompted to enter the following details: +- Host name +- HostName (IP address or domain) +- User (default: current user) +- Port (default: 22) +- IdentityFile (default: `~/.ssh/id_rsa`) + +### Editing an Existing SSH Host + +```bash +sshm edit myhost +``` + +You will be prompted to update the details for the host `myhost`. + +### Viewing a Host Configuration + +```bash +sshm view myhost +``` + +### Checking Host Availability + +```bash +sshm ping myhost +``` + +## License + +This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details. + +## Contributing + +Contributions are welcome! Please open an issue or submit a pull request. \ No newline at end of file diff --git a/sshm.bash b/sshm.bash new file mode 100755 index 0000000..1ba53b3 --- /dev/null +++ b/sshm.bash @@ -0,0 +1,285 @@ +#!/usr/bin/env bash + +############################################################################### +# Copyright 2024 Guillaume Archambault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################################################### + +set -eo pipefail; [[ $TRACE ]] && set -x + +readonly VERSION="1.0.0" + +ssh_manager_version() { + echo "ssh_manager $VERSION" +} + +ssh_manager_help() { + echo "Usage: ssh_manager command " + echo + cat<, Connect to SSH host by number or name + ping , Ping an SSH host to check availability + view , Check configuration of host + delete , Delete an SSH host from the configuration + add, Add an SSH host to the configuration + help, Displays help + version, Displays the current version +EOF + echo +} + +ssh_manager_list() { + local config_file=~/.ssh/config + echo -e "\nList of SSH hosts:" + grep -E '^Host ' "$config_file" | awk '{print $2}' | grep -v '^#' | nl + + echo -ne "\nEnter the number or name of the host (or press Enter to exit): " + read host + if [[ -z "$host" ]]; then + echo "No host specified, exiting." + exit 0 + fi + + ssh_manager_connect "$host" +} + +ssh_manager_connect() { + local config_file=~/.ssh/config + local host="$1" + if [[ -z "$host" ]]; then + echo "Error: please provide a host number or name." 1>&2 + exit 1 + fi + if [[ "$host" =~ ^[0-9]+$ ]]; then + local host_name + host_name=$(grep -E '^Host ' "$config_file" | awk '{print $2}' | grep -v '^#' | sed -n "${host}p") + if [ -n "$host_name" ]; then + ssh "$host_name" + else + echo "Invalid number." 1>&2 + exit 2 + fi + else + ssh "$host" + fi +} + +ssh_manager_ping() { + local config_file=~/.ssh/config + local host="$1" + if [[ -z "$host" ]]; then + echo "Error: please provide a host name." 1>&2 + exit 1 + fi + + local hostname + hostname=$(awk '/^Host '"$host"'$/,/^$/' "$config_file" | awk '/HostName/ {print $2}') + if [[ -z "$hostname" ]]; then + echo "Error: HostName not found for host $host in SSH configuration." 1>&2 + exit 1 + fi + + if ping -c 1 -W 1 "$hostname" &> /dev/null; then + echo -e "\033[32m$host ($hostname) is available\033[0m" + else + echo -e "\033[31m$host ($hostname) is unavailable\033[0m" + fi +} + +ssh_manager_view() { + local config_file=~/.ssh/config + local host="$1" + if [[ -z "$host" ]]; then + echo "Error: please provide a host name." 1>&2 + exit 1 + fi + + local host_info + host_info=$(awk '/^Host '"$host"'$/,/^$/' "$config_file") + if [[ -z "$host_info" ]]; then + echo "Error: host not found in SSH configuration." 1>&2 + exit 1 + fi + + echo -e "\nInformation for host $host:\n" + echo "$host_info" +} + +ssh_manager_delete() { + local config_file=~/.ssh/config + local host="$1" + if [[ -z "$host" ]]; then + echo "Error: please provide a host name." 1>&2 + exit 1 + fi + + local tmp_file=$(mktemp) + sed '/^Host '"$host"'$/,/^$/d' "$config_file" > "$tmp_file" + mv "$tmp_file" "$config_file" + echo "Host $host removed from SSH configuration." +} + +ssh_manager_add() { + local config_file=~/.ssh/config + local host="$1" + local hostname + local user + local port + local identity_file + + # Request necessary information + if [[ -z "$host" ]]; then + read -p "Enter host name: " host + if [[ -z "$host" ]]; then + echo "Error: host name cannot be empty." 1>&2 + exit 1 + fi + fi + + read -p "Enter HostName (IP address or domain): " hostname + if [[ -z "$hostname" ]]; then + echo "Error: HostName cannot be empty." 1>&2 + exit 1 + fi + + read -p "Enter user name (default: $(whoami)): " user + user=${user:-$(whoami)} + + read -p "Enter SSH port (default: 22): " port + port=${port:-22} + + read -p "Enter path to SSH key (default: ~/.ssh/id_rsa): " identity_file + identity_file=${identity_file:-~/.ssh/id_rsa} + + # Add the new configuration to the file + { + echo "" + echo "Host $host" + echo " HostName $hostname" + echo " User $user" + if [[ "$port" -ne 22 ]]; then + echo " Port $port" + fi + if [[ "$identity_file" != ~/.ssh/id_rsa ]]; then + echo " IdentityFile $identity_file" + fi + } >> "$config_file" + + echo "Configuration for host $host added successfully." +} + +ssh_manager_edit() { + local config_file=~/.ssh/config + local host="$1" + if [[ -z "$host" ]]; then + echo "Error: please provide a host name." 1>&2 + exit 1 + fi + + local host_info + host_info=$(awk '/^Host '"$host"'$/,/^$/' "$config_file") + if [[ -z "$host_info" ]]; then + echo "Error: host not found in SSH configuration." 1>&2 + exit 1 + fi + + # Extract current values + local current_hostname=$(echo "$host_info" | awk '/HostName/ {print $2}') + local current_user=$(echo "$host_info" | awk '/User/ {print $2}') + local current_port=$(echo "$host_info" | awk '/Port/ {print $2}') + local current_identity_file=$(echo "$host_info" | awk '/IdentityFile/ {print $2}') + + # Prompt for new values, defaulting to current values if no input is given + read -p "HostName [$current_hostname]: " new_hostname + new_hostname=${new_hostname:-$current_hostname} + + read -p "User [$current_user]: " new_user + new_user=${new_user:-$current_user} + + read -p "Port [${current_port:-22}]: " new_port + new_port=${new_port:-${current_port:-22}} + + read -p "IdentityFile [${current_identity_file:-~/.ssh/id_rsa}]: " new_identity_file + new_identity_file=${new_identity_file:-${current_identity_file:-~/.ssh/id_rsa}} + + # Delete the old configuration + ssh_manager_delete "$host" + + # Add the new configuration + { + echo "" + echo "Host $host" + echo " HostName $new_hostname" + echo " User $new_user" + if [[ "$new_port" -ne 22 ]]; then + echo " Port $new_port" + fi + if [[ "$new_identity_file" != ~/.ssh/id_rsa ]]; then + echo " IdentityFile $new_identity_file" + fi + } >> "$config_file" + + echo "Configuration for host $host updated successfully." +} + + +ssh_manager_main() { + local command="$1" + + if [[ -z $command ]]; then + ssh_manager_version + echo + ssh_manager_help + exit 0 + fi + + shift 1 + case "$command" in + "list") + ssh_manager_list + ;; + "connect") + ssh_manager_connect "$@" + ;; + "ping") + ssh_manager_ping "$@" + ;; + "view") + ssh_manager_view "$@" + ;; + "delete") + ssh_manager_delete "$@" + ;; + "add") + ssh_manager_add "$@" + ;; + "edit") + ssh_manager_edit "$@" + ;; + "version") + ssh_manager_version + ;; + "help") + ssh_manager_help + ;; + *) + ssh_manager_help 1>&2 + exit 3 + esac +} + +if [[ "$0" == "$BASH_SOURCE" ]]; then + ssh_manager_main "$@" +fi