> [!WARNING]
> There is no "stable" version published on pypip yet. This tool is under development.
<p align="center" >
<img src="logo.png" alt="logo" width="250"/>
<h3 align="center">cloudsnake 🐍</h3>
<p align="center">Wrapping some awscli commands with beautiful TUI</p>
<p align="center">Build with ❤ in Python</p>
</p>
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Why cloudsnake](#why-cloudsnake)
- [Badges](#badges)
- [Available implementations](#available-implementations)
- [Examples](#examples)
- [Connect to the EC2 instance using SSM](#connect-to-the-ec2-instance-using-ssm)
- [Example](#example)
- [Connect to the RDS instance using IAM authentication db token](#connect-to-the-rds-instance-using-iam-authentication-db-token)
- [Download the cert](#download-the-cert)
- [Connect to the instance](#connect-to-the-instance)
- [Example](#example-1)
- [Installation](#installation)
- [Using pip](#using-pip)
- [Using pipx with virtualenv (recommended)](#using-pipx-with-virtualenv-recommended)
- [Local install](#local-install)
- [Uninstall](#uninstall)
- [Using pip](#using-pip-1)
- [Using pipx](#using-pipx)
- [Local development](#local-development)
- [Local run with poetry](#local-run-with-poetry)
- [Run & install pre-commit](#run--install-pre-commit)
- [Testing](#testing)
- [TO DO](#to-do)
- [Improvements](#improvements)
- [Positional flags](#positional-flags)
- [Actually](#actually)
- [Wants](#wants)
- [TOP LINKS](#top-links)
- [Poetry commands](#poetry-commands)
- [Cloudsnake commands](#cloudsnake-commands)
- [License](#license)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
![example](./example.png)
# Why cloudsnake
The main intention of this tool is to continue improving my python skills, get to know the AWS [boto3](https://aws.amazon.com/es/sdk-for-python/) SDK better, and learn how to create a CLI using [typer](https://typer.tiangolo.com/), [rich](https://github.com/Textualize/rich), and [textual](https://textual.textualize.io/). The tool tries to implement some commands from the official AWS cli ([aws cli](https://github.com/aws/aws-cli)), adding my own logic and with highlights (pretty print json output/table with typer/rich).
> [!IMPORTANT]
> Do not try to use part of this code in a productive app as it is currently untested. (visit [#TO DO](https://github.com/containerscrew/cloudsnake?tab=readme-ov-file#to-do) section). I also don't know if this is the best way to use any of the tools that the application uses (boto3, typer, rich...), that is why any PR is welcome, it will be appreciated so I can continue improving my skills.
> [!IMPORTANT]
> In the end, the purpose of this tool is also to be able to facilitate the day to day, creating tools that help me to operate the platform. For example, to quickly connect to EC2, RDS...etc.
# Badges
| | |
|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Code | ![Code Size](https://img.shields.io/github/languages/code-size/containerscrew/tftools) |
| CI/CD | [![CI - Test](https://github.com/ofek/hatch-showcase/actions/workflows/test.yml/badge.svg)](https://github.com/ofek/hatch-showcase/actions/workflows/test.yml) [![CD - Build](https://github.com/containerscrew/cloudsnake/actions/workflows/build.yml/badge.svg)](https://github.com/containerscrew/cloudsnake/actions/workflows/build.yml) |
| Package | [![python](https://img.shields.io/badge/Python-3.12-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org)[![PyPI - Version](https://img.shields.io/pypi/v/hatch-showcase.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/hatch-showcase/) ![packaging](https://img.shields.io/badge/packaging-poetry-cyan.svg) |
| Meta | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/) |
| Linter | [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) |
# Available implementations
* Connect to EC2 instances using SSM. You can pass the instance id (`--target`) or use the interactive menu (`--with-instance-selector`)
* Connect to the RDS instances using IAM db authentication.
> See examples in the next section
# Examples
For the examples, you need to be authenticated to AWS account using your local credentials.
In your terminal, set the corresponding `AWS_PROFILE=MyProfile` if not using the default. (`~/.aws/credentials`)
## Connect to the EC2 instance using SSM
```shell
cloudsnake ssm start-session --with-instance-selector # will print all your instances in a terminal menu
cloudsnake ssm start-session --target i-XXXXXX # connect to the instance specifying the target id
```
### Example
![example_ssm_connect](./example_ssm_connect.png)
## Connect to the RDS instance using IAM authentication db token
Please follow [this instructions](./docs/rds.md) to setup your RDS IAM authentication.
### Download the cert
By default, `cloudsnake` forces to use TLS/SSL connections.
```shell
cloudsnake rds download-cert --save-path /tmp
```
Other region:
```shell
cloudsnake --region us-east-1 download-cert --save-path /tmp
```
### Connect to the instance
Example for the region `eu-west-1`:
```shell
cloudsnake rds connect -h XXXXX.XXXXXX.eu-west-1.rds.amazonaws.com -u ADMIN --cert /tmp/rds-cert-eu-west-1.pem
```
### Example
![example_rds](./example_rds.png)
# Installation
## Using pip
```console
pip3 install cloudsnake
```
> [!WARNING]
> Probably your system will not allow this installation method due to a broken system package.
<details>
<summary>Example error</summary>
<br>
Error:
<br><br>
<pre>
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try 'pacman -S
python-xyz', where xyz is the package you are trying to
install.
If you wish to install a non-Arch-packaged Python package,
create a virtual environment using 'python -m venv path/to/venv'.
Then use path/to/venv/bin/python and path/to/venv/bin/pip.
If you wish to install a non-Arch packaged Python application,
it may be easiest to use 'pipx install xyz', which will manage a
virtual environment for you. Make sure you have python-pipx
installed via pacman.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
</pre>
</details>
## Using pipx with virtualenv (recommended)
Install `pipx` with your system package manager (`apt`, `dnf`, `pacman`...).
```console
pipx install cloudsnake
```
## Local install
```console
git clone https://github.com/containerscrew/cloudsnake.git
cd cloudsnake
make pipx-local-install
```
# Uninstall
## Using pip
```console
pip3 uninstall cloudsnake
```
## Using pipx
```console
pipx uninstall cloudsnake
```
# Local development
## Local run with poetry
```console
git clone https://github.com/containerscrew/cloudsnake.git
cd cloudsnake
make update
make run
```
## Run & install pre-commit
```console
make pre-commit-install
make run-pre-commit
```
## Testing
```shell
git clone https://github.com/containerscrew/cloudsnake.git
cd cloudsnake
make run-tests
```
# TO DO
* Documentation with docstrings
* Add more tests with pytest and boto3 mock
* Remove @classmethod
* Ruff linter
* Cliff: changelog
* Pipelines with github actions. Automatic publish new version to `pypip`
* Other...
# Improvements
## Positional flags
### Actually
```shell
cloudsnake --log-level debug --region us-east-1 --profile default ec2 describe-instance
```
### Wants
```shell
cloudsnake ec2 describe-instances --log-level debug --region us-east-1 --profile default --other-specific-flags-for-this-subdommand
```
# TOP LINKS
[`links.md`](./docs/links.md)
# Poetry commands
[`poetry.md`](./docs/poetry.md)
# Cloudsnake commands
```shell
cloudsnake --help
cloudsnake ec2 describe-instances --filters "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].{Instance:InstanceId,VpcId:VpcId,AZ:Placement.AvailabilityZone,Name:Tags[?Key==`Name`]|[0].Value}' --output json
cloudsnake ec2 describe-instances --filters "Name=instance-state-name,Values=running" --output json
cloudsnake ec2 describe-instances --filters "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].{InstanceName:Tags[?Key==`Name`]|[0].Value}' --output json
cloudsnake ec2 describe-instances --filters "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].Tags[?Key==`Name`].Value[][]'
cloudsnake rds describe-db-instances --query 'DBInstances[*].DBInstanceIdentifier'
cloudsnake ssm start-session --with-instance-selector
cloudsnake ssm start-session --target i-xxxxxxx
```
# License
`cloudsnake` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
Raw data
{
"_id": null,
"home_page": "https://github.com/containerscrew/cloudsnake",
"name": "cloudsnake",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.12",
"maintainer_email": null,
"keywords": "aws, cli, rich, textual, cloudsnake",
"author": "containerscrew",
"author_email": "info@containerscrew.com",
"download_url": "https://files.pythonhosted.org/packages/d3/80/c08282f19df6676aa1319060b780cee82407a7c1493207a01a2064bf88f9/cloudsnake-0.4.0.tar.gz",
"platform": null,
"description": "> [!WARNING]\n> There is no \"stable\" version published on pypip yet. This tool is under development.\n\n\n<p align=\"center\" >\n <img src=\"logo.png\" alt=\"logo\" width=\"250\"/>\n <h3 align=\"center\">cloudsnake \ud83d\udc0d</h3>\n <p align=\"center\">Wrapping some awscli commands with beautiful TUI</p>\n <p align=\"center\">Build with \u2764 in Python</p>\n</p>\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [Why cloudsnake](#why-cloudsnake)\n- [Badges](#badges)\n- [Available implementations](#available-implementations)\n- [Examples](#examples)\n - [Connect to the EC2 instance using SSM](#connect-to-the-ec2-instance-using-ssm)\n - [Example](#example)\n - [Connect to the RDS instance using IAM authentication db token](#connect-to-the-rds-instance-using-iam-authentication-db-token)\n - [Download the cert](#download-the-cert)\n - [Connect to the instance](#connect-to-the-instance)\n - [Example](#example-1)\n- [Installation](#installation)\n - [Using pip](#using-pip)\n - [Using pipx with virtualenv (recommended)](#using-pipx-with-virtualenv-recommended)\n - [Local install](#local-install)\n- [Uninstall](#uninstall)\n - [Using pip](#using-pip-1)\n - [Using pipx](#using-pipx)\n- [Local development](#local-development)\n - [Local run with poetry](#local-run-with-poetry)\n - [Run & install pre-commit](#run--install-pre-commit)\n - [Testing](#testing)\n- [TO DO](#to-do)\n- [Improvements](#improvements)\n - [Positional flags](#positional-flags)\n - [Actually](#actually)\n - [Wants](#wants)\n- [TOP LINKS](#top-links)\n- [Poetry commands](#poetry-commands)\n- [Cloudsnake commands](#cloudsnake-commands)\n- [License](#license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n![example](./example.png)\n\n# Why cloudsnake\n\nThe main intention of this tool is to continue improving my python skills, get to know the AWS [boto3](https://aws.amazon.com/es/sdk-for-python/) SDK better, and learn how to create a CLI using [typer](https://typer.tiangolo.com/), [rich](https://github.com/Textualize/rich), and [textual](https://textual.textualize.io/). The tool tries to implement some commands from the official AWS cli ([aws cli](https://github.com/aws/aws-cli)), adding my own logic and with highlights (pretty print json output/table with typer/rich).\n\n> [!IMPORTANT]\n> Do not try to use part of this code in a productive app as it is currently untested. (visit [#TO DO](https://github.com/containerscrew/cloudsnake?tab=readme-ov-file#to-do) section). I also don't know if this is the best way to use any of the tools that the application uses (boto3, typer, rich...), that is why any PR is welcome, it will be appreciated so I can continue improving my skills.\n\n> [!IMPORTANT]\n> In the end, the purpose of this tool is also to be able to facilitate the day to day, creating tools that help me to operate the platform. For example, to quickly connect to EC2, RDS...etc.\n\n# Badges\n\n| | |\n|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Code | ![Code Size](https://img.shields.io/github/languages/code-size/containerscrew/tftools) |\n| CI/CD | [![CI - Test](https://github.com/ofek/hatch-showcase/actions/workflows/test.yml/badge.svg)](https://github.com/ofek/hatch-showcase/actions/workflows/test.yml) [![CD - Build](https://github.com/containerscrew/cloudsnake/actions/workflows/build.yml/badge.svg)](https://github.com/containerscrew/cloudsnake/actions/workflows/build.yml) |\n| Package | [![python](https://img.shields.io/badge/Python-3.12-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org)[![PyPI - Version](https://img.shields.io/pypi/v/hatch-showcase.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/hatch-showcase/) ![packaging](https://img.shields.io/badge/packaging-poetry-cyan.svg) |\n| Meta | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/) |\n| Linter | [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) |\n\n\n# Available implementations\n\n* Connect to EC2 instances using SSM. You can pass the instance id (`--target`) or use the interactive menu (`--with-instance-selector`)\n\n* Connect to the RDS instances using IAM db authentication.\n\n> See examples in the next section\n\n# Examples\n\nFor the examples, you need to be authenticated to AWS account using your local credentials.\n\nIn your terminal, set the corresponding `AWS_PROFILE=MyProfile` if not using the default. (`~/.aws/credentials`)\n\n## Connect to the EC2 instance using SSM\n\n```shell\ncloudsnake ssm start-session --with-instance-selector # will print all your instances in a terminal menu\ncloudsnake ssm start-session --target i-XXXXXX # connect to the instance specifying the target id\n```\n\n### Example\n\n![example_ssm_connect](./example_ssm_connect.png)\n\n## Connect to the RDS instance using IAM authentication db token\n\nPlease follow [this instructions](./docs/rds.md) to setup your RDS IAM authentication.\n\n### Download the cert\n\nBy default, `cloudsnake` forces to use TLS/SSL connections.\n\n```shell\ncloudsnake rds download-cert --save-path /tmp\n```\n\nOther region:\n\n```shell\ncloudsnake --region us-east-1 download-cert --save-path /tmp\n```\n\n### Connect to the instance\n\nExample for the region `eu-west-1`:\n\n```shell\ncloudsnake rds connect -h XXXXX.XXXXXX.eu-west-1.rds.amazonaws.com -u ADMIN --cert /tmp/rds-cert-eu-west-1.pem\n```\n\n### Example\n\n![example_rds](./example_rds.png)\n\n# Installation\n\n## Using pip\n\n```console\npip3 install cloudsnake\n```\n> [!WARNING]\n> Probably your system will not allow this installation method due to a broken system package.\n\n<details>\n<summary>Example error</summary>\n<br>\nError:\n<br><br>\n<pre>\nerror: externally-managed-environment\n\n\u00d7 This environment is externally managed\n\u2570\u2500> To install Python packages system-wide, try 'pacman -S\n python-xyz', where xyz is the package you are trying to\n install.\n\n If you wish to install a non-Arch-packaged Python package,\n create a virtual environment using 'python -m venv path/to/venv'.\n Then use path/to/venv/bin/python and path/to/venv/bin/pip.\n\n If you wish to install a non-Arch packaged Python application,\n it may be easiest to use 'pipx install xyz', which will manage a\n virtual environment for you. Make sure you have python-pipx\n installed via pacman.\n\nnote: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.\nhint: See PEP 668 for the detailed specification.\n</pre>\n</details>\n\n## Using pipx with virtualenv (recommended)\n\nInstall `pipx` with your system package manager (`apt`, `dnf`, `pacman`...).\n\n```console\npipx install cloudsnake\n```\n\n## Local install\n\n```console\ngit clone https://github.com/containerscrew/cloudsnake.git\ncd cloudsnake\nmake pipx-local-install\n```\n\n# Uninstall\n\n## Using pip\n\n```console\npip3 uninstall cloudsnake\n```\n\n## Using pipx\n\n```console\npipx uninstall cloudsnake\n```\n\n# Local development\n\n## Local run with poetry\n\n```console\ngit clone https://github.com/containerscrew/cloudsnake.git\ncd cloudsnake\nmake update\nmake run\n```\n\n## Run & install pre-commit\n\n```console\nmake pre-commit-install\nmake run-pre-commit\n```\n\n## Testing\n\n```shell\ngit clone https://github.com/containerscrew/cloudsnake.git\ncd cloudsnake\nmake run-tests\n```\n\n# TO DO\n\n* Documentation with docstrings\n* Add more tests with pytest and boto3 mock\n* Remove @classmethod\n* Ruff linter\n* Cliff: changelog\n* Pipelines with github actions. Automatic publish new version to `pypip`\n* Other...\n\n# Improvements\n\n## Positional flags\n\n### Actually\n\n```shell\ncloudsnake --log-level debug --region us-east-1 --profile default ec2 describe-instance\n```\n\n### Wants\n\n```shell\ncloudsnake ec2 describe-instances --log-level debug --region us-east-1 --profile default --other-specific-flags-for-this-subdommand\n```\n\n# TOP LINKS\n\n[`links.md`](./docs/links.md)\n\n# Poetry commands\n\n[`poetry.md`](./docs/poetry.md)\n\n# Cloudsnake commands\n\n```shell\ncloudsnake --help\ncloudsnake ec2 describe-instances --filters \"Name=instance-state-name,Values=running\" --query 'Reservations[*].Instances[*].{Instance:InstanceId,VpcId:VpcId,AZ:Placement.AvailabilityZone,Name:Tags[?Key==`Name`]|[0].Value}' --output json\ncloudsnake ec2 describe-instances --filters \"Name=instance-state-name,Values=running\" --output json\ncloudsnake ec2 describe-instances --filters \"Name=instance-state-name,Values=running\" --query 'Reservations[*].Instances[*].{InstanceName:Tags[?Key==`Name`]|[0].Value}' --output json\ncloudsnake ec2 describe-instances --filters \"Name=instance-state-name,Values=running\" --query 'Reservations[*].Instances[*].Tags[?Key==`Name`].Value[][]'\ncloudsnake rds describe-db-instances --query 'DBInstances[*].DBInstanceIdentifier'\ncloudsnake ssm start-session --with-instance-selector\ncloudsnake ssm start-session --target i-xxxxxxx\n```\n\n# License\n\n`cloudsnake` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Wrapping some awscli commands with beautiful TUI",
"version": "0.4.0",
"project_urls": {
"Documentation": "https://github.com/containerscrew/cloudsnake#readme",
"Homepage": "https://github.com/containerscrew/cloudsnake",
"Repository": "https://github.com/containerscrew/cloudsnake"
},
"split_keywords": [
"aws",
" cli",
" rich",
" textual",
" cloudsnake"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ca7ce60c30e590232afb4b69cab407b0ead7612f55a29c691c29ff6be1519fb6",
"md5": "a4733c9014023b748bba3b70377fccee",
"sha256": "1a2ce16a3caa308426552004eab291cf5962af61a5afdc3c3e37e895f33919f7"
},
"downloads": -1,
"filename": "cloudsnake-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a4733c9014023b748bba3b70377fccee",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.12",
"size": 21952,
"upload_time": "2024-06-28T11:33:47",
"upload_time_iso_8601": "2024-06-28T11:33:47.705220Z",
"url": "https://files.pythonhosted.org/packages/ca/7c/e60c30e590232afb4b69cab407b0ead7612f55a29c691c29ff6be1519fb6/cloudsnake-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d380c08282f19df6676aa1319060b780cee82407a7c1493207a01a2064bf88f9",
"md5": "8cfb5b21c09cc0d4bcae205957b533ed",
"sha256": "568786e285334da8e0999d90df0fde8cb1c0657e293c8db0d6255b5dad0eec5c"
},
"downloads": -1,
"filename": "cloudsnake-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "8cfb5b21c09cc0d4bcae205957b533ed",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.12",
"size": 21312,
"upload_time": "2024-06-28T11:33:49",
"upload_time_iso_8601": "2024-06-28T11:33:49.684142Z",
"url": "https://files.pythonhosted.org/packages/d3/80/c08282f19df6676aa1319060b780cee82407a7c1493207a01a2064bf88f9/cloudsnake-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-28 11:33:49",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "containerscrew",
"github_project": "cloudsnake",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "cloudsnake"
}