Skip to content

Commit

Permalink
Add CLI functionality
Browse files Browse the repository at this point in the history
Update README.md
Create new workflow to validate hyperlinks
  • Loading branch information
dormant-user committed Aug 13, 2024
1 parent 5e7cdbb commit 594b200
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 11 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/markdown.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: none-shall-pass

on:
push:
branches:
- main
paths:
- '**/*.md'
workflow_dispatch:

jobs:
none-shall-pass:
runs-on: thevickypedia-lite
steps:
- uses: thevickypedia/none-shall-pass@v5
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ venv/
__pycache__/

build/
PyNinja.egg-info/
nctl.egg-info/

doc_gen/_*

Expand Down
144 changes: 144 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,146 @@
# NCTL
Fuses ngrok and CloudFront offering a fully automated solution

![Python][label-pyversion]

**Platform Supported**

![Platform][label-platform]

**Deployments**

[![pages][label-actions-pages]][gha_pages]
[![pypi][label-actions-pypi]][gha_pypi]
[![markdown][label-actions-markdown]][gha_md_valid]

[![Pypi][label-pypi]][pypi]
[![Pypi-format][label-pypi-format]][pypi-files]
[![Pypi-status][label-pypi-status]][pypi]

## Kick off

**Recommendations**

- Install `python` [3.10] or [3.11]
- Use a dedicated [virtual environment]

**Install nctl**
```shell
python -m pip install nctl
```

**Initiate - IDE**
```python
import nctl


if __name__ == '__main__':
nctl.tunnel()
```

**Initiate - CLI**
```shell
nctl start
```

> Use `nctl --help` for usage instructions.
## Environment Variables

<details>
<summary><strong>Sourcing environment variables from an env file</strong></summary>

> _By default, `nctl` will look for a `.env` file in the current working directory._<br>
> Refer [samples] directory for examples.
</details>

- **PORT** - Port number to expose using ngrok.
- **HOST** - Hostname of the server that has to be exposed.
- **NGROK_AUTH** - Auth token for ngrok.
- **NGROK_CONFIG** - Ngrok configuration filepath. Auto-created when auth token is specified.
- **DISTRIBUTION_ID** - Cloudfront distribution ID. Required to update an existing distribution.
- **DISTRIBUTION_CONFIG** - Cloudfront distribution config filepath. Required to create a new distribution.
- **DEBUG** - Boolean flag to enable debug level logging.

#### AWS Config

- **AWS_PROFILE_NAME** - AWS profile name.
- **AWS_ACCESS_KEY_ID** - AWS access key ID.
- **AWS_SECRET_ACCESS_KEY** - AWS secret key.
- **AWS_REGION_NAME** - AWS region name.

## Coding Standards
Docstring format: [`Google`][google-docs] <br>
Styling conventions: [`PEP 8`][pep8] and [`isort`][isort]

## [Release Notes][release-notes]
**Requirement**
```shell
python -m pip install gitverse
```

**Usage**
```shell
gitverse-release reverse -f release_notes.rst -t 'Release Notes'
```

## Linting
`pre-commit` will ensure linting, run pytest, generate runbook & release notes, and validate hyperlinks in ALL
markdown files (including Wiki pages)

**Requirement**
```shell
python -m pip install sphinx==5.1.1 pre-commit recommonmark
```

**Usage**
```shell
pre-commit run --all-files
```

## Pypi Package
[![pypi-module][label-pypi-package]][pypi-repo]

[https://pypi.org/project/nctl/][pypi]

## Runbook
[![made-with-sphinx-doc][label-sphinx-doc]][sphinx]

[https://thevickypedia.github.io/nctl/][runbook]

## License & copyright

&copy; Vignesh Rao

Licensed under the [MIT License][license]

[//]: # (Labels)

[label-actions-markdown]: https://github.com/thevickypedia/nctl/actions/workflows/markdown.yaml/badge.svg
[label-pypi-package]: https://img.shields.io/badge/Pypi%20Package-nctl-blue?style=for-the-badge&logo=Python
[label-sphinx-doc]: https://img.shields.io/badge/Made%20with-Sphinx-blue?style=for-the-badge&logo=Sphinx
[label-pyversion]: https://img.shields.io/badge/python-3.10%20%7C%203.11-blue
[label-platform]: https://img.shields.io/badge/Platform-Linux|macOS|Windows-1f425f.svg
[label-actions-pages]: https://github.com/thevickypedia/nctl/actions/workflows/pages/pages-build-deployment/badge.svg
[label-actions-pypi]: https://github.com/thevickypedia/nctl/actions/workflows/python-publish.yaml/badge.svg
[label-pypi]: https://img.shields.io/pypi/v/nctl
[label-pypi-format]: https://img.shields.io/pypi/format/nctl
[label-pypi-status]: https://img.shields.io/pypi/status/nctl

[3.10]: https://docs.python.org/3/whatsnew/3.10.html
[3.11]: https://docs.python.org/3/whatsnew/3.11.html
[virtual environment]: https://docs.python.org/3/tutorial/venv.html
[release-notes]: https://github.com/thevickypedia/nctl/blob/master/release_notes.rst
[gha_pages]: https://github.com/thevickypedia/nctl/actions/workflows/pages/pages-build-deployment
[gha_pypi]: https://github.com/thevickypedia/nctl/actions/workflows/python-publish.yaml
[gha_md_valid]: https://github.com/thevickypedia/nctl/actions/workflows/markdown.yaml
[google-docs]: https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
[pep8]: https://www.python.org/dev/peps/pep-0008/
[isort]: https://pycqa.github.io/isort/
[sphinx]: https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html
[pypi]: https://pypi.org/project/nctl
[pypi-files]: https://pypi.org/project/nctl/#files
[pypi-repo]: https://packaging.python.org/tutorials/packaging-projects/
[license]: https://github.com/thevickypedia/nctl/blob/master/LICENSE
[runbook]: https://thevickypedia.github.io/nctl/
68 changes: 65 additions & 3 deletions nctl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,68 @@
"""Placeholder for packaging."""

import sys

import click

from nctl.main import tunnel # noqa: F401

version = "0.0.0-a"


def commandline():
"""Work in progress."""
pass
@click.command()
@click.argument("start", required=False)
@click.argument("run", required=False)
@click.option("--version", "-V", is_flag=True, help="Prints the version.")
@click.option("--help", "-H", is_flag=True, help="Prints the help section.")
@click.option(
"--env",
"-E",
type=click.Path(exists=True),
help="Environment configuration filepath.",
)
def commandline(*args, **kwargs) -> None:
"""Starter function to invoke nctl via CLI commands.
**Flags**
- ``--version | -V``: Prints the version.
- ``--help | -H``: Prints the help section.
- ``--env | -E``: Environment configuration filepath.
**Commands**
``start | run``: Initiates the backup process.
"""
assert sys.argv[0].lower().endswith("nctl"), "Invalid commandline trigger!!"
options = {
"--version | -V": "Prints the version.",
"--help | -H": "Prints the help section.",
"--env | -E": "Environment configuration filepath.",
"start | run": "Initiates the backup process.",
}
# weird way to increase spacing to keep all values monotonic
_longest_key = len(max(options.keys()))
_pretext = "\n\t* "
choices = _pretext + _pretext.join(
f"{k} {'·' * (_longest_key - len(k) + 8)}{v}".expandtabs()
for k, v in options.items()
)
if kwargs.get("version"):
click.echo(f"nctl {version}")
sys.exit(0)
if kwargs.get("help"):
click.echo(
f"\nUsage: nctl [arbitrary-command]\nOptions (and corresponding behavior):{choices}"
)
sys.exit(0)
trigger = kwargs.get("start") or kwargs.get("run")
if trigger and trigger.lower() in ("start", "run"):
# Click doesn't support assigning defaults like traditional dictionaries, so kwargs.get("max", 100) won't work
tunnel(env_file=kwargs.get("env"))
sys.exit(0)
elif trigger:
click.secho(f"\n{trigger!r} - Invalid command", fg="red")
else:
click.secho("\nNo command provided", fg="red")
click.echo(
f"Usage: nctl [arbitrary-command]\nOptions (and corresponding behavior):{choices}"
)
sys.exit(1)
12 changes: 9 additions & 3 deletions nctl/cloudfront.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import yaml
from botocore.exceptions import ClientError

from src import models
from src.logger import LOGGER
from nctl import models
from nctl.logger import LOGGER


class CloudFront:
Expand All @@ -26,10 +26,16 @@ def __init__(self, env_dump: dict):
Args:
env_dump: JSON dump of environment variables' configuration.
"""
self.client = boto3.client("cloudfront")
self.env = models.EnvConfig(**env_dump)
if self.env.debug:
LOGGER.setLevel(logging.DEBUG)
session = boto3.Session(
aws_access_key_id=self.env.aws_access_key_id,
aws_secret_access_key=self.env.aws_secret_access_key,
region_name=self.env.aws_region_name,
profile_name=self.env.aws_profile_name,
)
self.client = session.client("cloudfront")

def run(self, public_url: str) -> None:
"""Updates the distribution if ID is available, otherwise creates a new distribution.
Expand Down
4 changes: 2 additions & 2 deletions nctl/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import os
import subprocess

from src import cloudfront, models, squire
from src.logger import LOGGER
from nctl import cloudfront, models, squire
from nctl.logger import LOGGER


# Have this as a dedicated function to avoid pickling error
Expand Down
1 change: 1 addition & 0 deletions nctl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class EnvConfig(BaseSettings):

port: PositiveInt
host: str = socket.gethostbyname("localhost") or "0.0.0.0"
aws_profile_name: str | None = None
aws_access_key_id: str | None = None
aws_secret_access_key: str | None = None
aws_default_region: str | None = None
Expand Down
4 changes: 2 additions & 2 deletions nctl/squire.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

import yaml

from src import models
from src.logger import LOGGER
from nctl import models
from nctl.logger import LOGGER


def create_ngrok_config(token: str, filename: str) -> None:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
boto3==1.34.158
botocore==1.34.158
click==8.1.7
pydantic==2.8.2
pydantic-settings==2.4.0
PyYaml==6.0.2

0 comments on commit 594b200

Please sign in to comment.