vm-tool 1.0.32__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- examples/README.md +5 -0
- examples/__init__.py +1 -0
- examples/cloud/README.md +3 -0
- examples/cloud/__init__.py +1 -0
- examples/cloud/ssh_identity_file.py +27 -0
- examples/cloud/ssh_password.py +27 -0
- examples/cloud/template_cloud_setup.py +36 -0
- examples/deploy_full_setup.py +44 -0
- examples/docker-compose.example.yml +47 -0
- examples/ec2-setup.sh +95 -0
- examples/github-actions-ec2.yml +245 -0
- examples/github-actions-full-setup.yml +58 -0
- examples/local/.keep +1 -0
- examples/local/README.md +3 -0
- examples/local/__init__.py +1 -0
- examples/local/template_local_setup.py +27 -0
- examples/production-deploy.sh +70 -0
- examples/rollback.sh +52 -0
- examples/setup.sh +52 -0
- examples/ssh_key_management.py +22 -0
- examples/version_check.sh +3 -0
- vm_tool/__init__.py +0 -0
- vm_tool/alerting.py +274 -0
- vm_tool/audit.py +118 -0
- vm_tool/backup.py +125 -0
- vm_tool/benchmarking.py +200 -0
- vm_tool/cli.py +761 -0
- vm_tool/cloud.py +125 -0
- vm_tool/completion.py +200 -0
- vm_tool/compliance.py +104 -0
- vm_tool/config.py +92 -0
- vm_tool/drift.py +98 -0
- vm_tool/generator.py +462 -0
- vm_tool/health.py +197 -0
- vm_tool/history.py +131 -0
- vm_tool/kubernetes.py +89 -0
- vm_tool/metrics.py +183 -0
- vm_tool/notifications.py +152 -0
- vm_tool/plugins.py +119 -0
- vm_tool/policy.py +197 -0
- vm_tool/rbac.py +140 -0
- vm_tool/recovery.py +169 -0
- vm_tool/reporting.py +218 -0
- vm_tool/runner.py +445 -0
- vm_tool/secrets.py +285 -0
- vm_tool/ssh.py +150 -0
- vm_tool/state.py +122 -0
- vm_tool/strategies/__init__.py +16 -0
- vm_tool/strategies/ab_testing.py +258 -0
- vm_tool/strategies/blue_green.py +227 -0
- vm_tool/strategies/canary.py +277 -0
- vm_tool/validation.py +267 -0
- vm_tool/vm_setup/cleanup.yml +27 -0
- vm_tool/vm_setup/docker/create_docker_service.yml +63 -0
- vm_tool/vm_setup/docker/docker_setup.yml +7 -0
- vm_tool/vm_setup/docker/install_docker_and_compose.yml +92 -0
- vm_tool/vm_setup/docker/login_to_docker_hub.yml +6 -0
- vm_tool/vm_setup/github/git_configuration.yml +68 -0
- vm_tool/vm_setup/inventory.yml +1 -0
- vm_tool/vm_setup/k8s.yml +15 -0
- vm_tool/vm_setup/main.yml +27 -0
- vm_tool/vm_setup/monitoring.yml +42 -0
- vm_tool/vm_setup/project_service.yml +17 -0
- vm_tool/vm_setup/push_code.yml +40 -0
- vm_tool/vm_setup/setup.yml +17 -0
- vm_tool/vm_setup/setup_project_env.yml +7 -0
- vm_tool/webhooks.py +83 -0
- vm_tool-1.0.32.dist-info/METADATA +213 -0
- vm_tool-1.0.32.dist-info/RECORD +73 -0
- vm_tool-1.0.32.dist-info/WHEEL +5 -0
- vm_tool-1.0.32.dist-info/entry_points.txt +2 -0
- vm_tool-1.0.32.dist-info/licenses/LICENSE +21 -0
- vm_tool-1.0.32.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
- name: Install Docker and Docker Compose on Ubuntu
|
|
2
|
+
block:
|
|
3
|
+
- name: Check if Docker is installed
|
|
4
|
+
ansible.builtin.command: docker --version
|
|
5
|
+
register: docker_installed
|
|
6
|
+
ignore_errors: yes
|
|
7
|
+
|
|
8
|
+
- name: Check if Docker Compose is installed
|
|
9
|
+
ansible.builtin.command: docker compose version
|
|
10
|
+
register: docker_compose_installed
|
|
11
|
+
ignore_errors: yes
|
|
12
|
+
|
|
13
|
+
- name: Log Docker installation status
|
|
14
|
+
ansible.builtin.debug:
|
|
15
|
+
msg: "Docker is {{ 'installed' if docker_installed.rc == 0 else 'not installed' }}"
|
|
16
|
+
|
|
17
|
+
- name: Log Docker Compose installation status
|
|
18
|
+
ansible.builtin.debug:
|
|
19
|
+
msg: "Docker Compose is {{ 'installed' if docker_compose_installed.rc == 0 else 'not installed' }}"
|
|
20
|
+
|
|
21
|
+
- name: Get system architecture
|
|
22
|
+
ansible.builtin.command: dpkg --print-architecture
|
|
23
|
+
register: system_arch
|
|
24
|
+
changed_when: false
|
|
25
|
+
|
|
26
|
+
- name: Get Ubuntu version codename
|
|
27
|
+
ansible.builtin.command: lsb_release -cs
|
|
28
|
+
register: ubuntu_codename
|
|
29
|
+
changed_when: false
|
|
30
|
+
|
|
31
|
+
- name: Update apt package index
|
|
32
|
+
ansible.builtin.apt:
|
|
33
|
+
update_cache: yes
|
|
34
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
35
|
+
|
|
36
|
+
- name: Install prerequisites
|
|
37
|
+
ansible.builtin.apt:
|
|
38
|
+
name:
|
|
39
|
+
- curl
|
|
40
|
+
- apt-transport-https
|
|
41
|
+
- ca-certificates
|
|
42
|
+
- gnupg
|
|
43
|
+
- lsb-release
|
|
44
|
+
- software-properties-common
|
|
45
|
+
state: present
|
|
46
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
47
|
+
|
|
48
|
+
- name: Add Docker GPG key
|
|
49
|
+
ansible.builtin.shell:
|
|
50
|
+
cmd: |
|
|
51
|
+
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
|
52
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
53
|
+
|
|
54
|
+
- name: Determine correct Ubuntu codename
|
|
55
|
+
set_fact:
|
|
56
|
+
ubuntu_codename_fixed: "{{ 'jammy' if ubuntu_codename.stdout == 'noble' else ubuntu_codename.stdout }}"
|
|
57
|
+
|
|
58
|
+
- name: Add Docker repository (auto-detect architecture)
|
|
59
|
+
ansible.builtin.shell:
|
|
60
|
+
cmd: |
|
|
61
|
+
echo "deb [arch={{ system_arch.stdout }} signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu {{ ubuntu_codename_fixed }} stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
62
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
63
|
+
|
|
64
|
+
- name: Update apt package index again
|
|
65
|
+
ansible.builtin.apt:
|
|
66
|
+
update_cache: yes
|
|
67
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
68
|
+
|
|
69
|
+
- name: Install Docker and Docker Compose (if available in repo)
|
|
70
|
+
ansible.builtin.apt:
|
|
71
|
+
name:
|
|
72
|
+
- docker-ce
|
|
73
|
+
- docker-ce-cli
|
|
74
|
+
- containerd.io
|
|
75
|
+
- docker-compose-plugin
|
|
76
|
+
state: present
|
|
77
|
+
ignore_errors: yes
|
|
78
|
+
register: docker_install_status
|
|
79
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
80
|
+
|
|
81
|
+
- name: Enable and Start Docker service
|
|
82
|
+
ansible.builtin.systemd:
|
|
83
|
+
name: docker
|
|
84
|
+
enabled: yes
|
|
85
|
+
state: started
|
|
86
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
87
|
+
|
|
88
|
+
- name: Change permissions for Docker socket
|
|
89
|
+
ansible.builtin.command: sudo chmod 666 /var/run/docker.sock
|
|
90
|
+
ignore_errors: yes
|
|
91
|
+
when: docker_installed.rc != 0 or docker_compose_installed.rc != 0
|
|
92
|
+
become: yes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
- name: Git Configuration Playbook
|
|
2
|
+
block:
|
|
3
|
+
- name: Ensure Git is installed
|
|
4
|
+
package:
|
|
5
|
+
name: git
|
|
6
|
+
state: present
|
|
7
|
+
become: yes
|
|
8
|
+
|
|
9
|
+
# --- Git Credential Setup ---
|
|
10
|
+
- name: Check if Git credentials file exists
|
|
11
|
+
stat:
|
|
12
|
+
path: ~/.git-credentials
|
|
13
|
+
register: git_credentials_stat
|
|
14
|
+
|
|
15
|
+
- name: Read contents of Git credentials file
|
|
16
|
+
slurp:
|
|
17
|
+
src: ~/.git-credentials
|
|
18
|
+
register: git_credentials_content
|
|
19
|
+
when: git_credentials_stat.stat.exists
|
|
20
|
+
|
|
21
|
+
- name: Decode Git credentials content
|
|
22
|
+
set_fact:
|
|
23
|
+
git_credentials: "{{ git_credentials_content.content | b64decode }}"
|
|
24
|
+
when: git_credentials_stat.stat.exists
|
|
25
|
+
|
|
26
|
+
- name: Fail if Git credentials not configured and vars not provided
|
|
27
|
+
fail:
|
|
28
|
+
msg: >
|
|
29
|
+
Git credentials not found and GITHUB_USERNAME/GITHUB_TOKEN not provided. Aborting.
|
|
30
|
+
when: >
|
|
31
|
+
(not git_credentials_stat.stat.exists or
|
|
32
|
+
("{{ GITHUB_USERNAME }}" not in git_credentials | default(''))) and
|
|
33
|
+
(GITHUB_USERNAME is not defined or GITHUB_TOKEN is not defined)
|
|
34
|
+
|
|
35
|
+
- name: Configure Git with GitHub token if not already configured
|
|
36
|
+
shell: |
|
|
37
|
+
git config --global credential.helper store
|
|
38
|
+
echo "https://{{ GITHUB_USERNAME }}:{{ GITHUB_TOKEN }}@github.com" > ~/.git-credentials
|
|
39
|
+
become: yes
|
|
40
|
+
when: >
|
|
41
|
+
(not git_credentials_stat.stat.exists or
|
|
42
|
+
("{{ GITHUB_USERNAME }}" not in git_credentials | default(''))) and
|
|
43
|
+
(GITHUB_USERNAME is defined and GITHUB_TOKEN is defined)
|
|
44
|
+
|
|
45
|
+
# --- Git Clone or Pull Logic ---
|
|
46
|
+
- name: Check if .git directory exists (repo already cloned)
|
|
47
|
+
stat:
|
|
48
|
+
path: "{{ project_dest_dir }}/.git"
|
|
49
|
+
register: project_dir_stat
|
|
50
|
+
|
|
51
|
+
- name: Pull latest changes if repository already exists
|
|
52
|
+
shell: |
|
|
53
|
+
cd {{ project_dest_dir }}
|
|
54
|
+
git remote set-url origin {{ GITHUB_PROJECT_URL }}
|
|
55
|
+
git fetch origin
|
|
56
|
+
git checkout {{ GITHUB_BRANCH }}
|
|
57
|
+
git pull origin {{ GITHUB_BRANCH }}
|
|
58
|
+
when: project_dir_stat.stat.exists
|
|
59
|
+
become: yes
|
|
60
|
+
|
|
61
|
+
- name: Clone the Project repository if not already cloned
|
|
62
|
+
git:
|
|
63
|
+
repo: "{{ GITHUB_PROJECT_URL }}"
|
|
64
|
+
dest: "{{ project_dest_dir }}"
|
|
65
|
+
version: "{{ GITHUB_BRANCH }}"
|
|
66
|
+
depth: 1
|
|
67
|
+
when: not project_dir_stat.stat.exists
|
|
68
|
+
become: yes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
localhost ansible_connection=local
|
vm_tool/vm_setup/k8s.yml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Install K3s
|
|
3
|
+
hosts: all
|
|
4
|
+
become: true
|
|
5
|
+
tasks:
|
|
6
|
+
- name: Install K3s
|
|
7
|
+
shell: curl -sfL https://get.k3s.io | sh -
|
|
8
|
+
args:
|
|
9
|
+
creates: /usr/local/bin/k3s
|
|
10
|
+
|
|
11
|
+
- name: Get Kubeconfig
|
|
12
|
+
fetch:
|
|
13
|
+
src: /etc/rancher/k3s/k3s.yaml
|
|
14
|
+
dest: "{{ lookup('env', 'HOME') }}/.kube/config_k3s"
|
|
15
|
+
flat: true
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
- name: Main Playbook
|
|
2
|
+
hosts: all
|
|
3
|
+
gather_facts: yes
|
|
4
|
+
|
|
5
|
+
tasks:
|
|
6
|
+
- name: Setup
|
|
7
|
+
include_tasks: setup.yml
|
|
8
|
+
|
|
9
|
+
- name: Git Configuration
|
|
10
|
+
include_tasks: github/git_configuration.yml
|
|
11
|
+
when: DEPLOY_MODE | default('pull') != 'push'
|
|
12
|
+
|
|
13
|
+
- name: Push Code (Zero Touch)
|
|
14
|
+
include_tasks: push_code.yml
|
|
15
|
+
when: DEPLOY_MODE | default('pull') == 'push'
|
|
16
|
+
|
|
17
|
+
- name: Setup Project Environment File
|
|
18
|
+
include_tasks: setup_project_env.yml
|
|
19
|
+
|
|
20
|
+
- name: Docker Setup
|
|
21
|
+
include_tasks: docker/docker_setup.yml
|
|
22
|
+
|
|
23
|
+
- name: Project Service
|
|
24
|
+
include_tasks: project_service.yml
|
|
25
|
+
|
|
26
|
+
- name: Cleanup
|
|
27
|
+
include_tasks: cleanup.yml
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Install Monitoring Stack
|
|
3
|
+
hosts: all
|
|
4
|
+
become: true
|
|
5
|
+
tasks:
|
|
6
|
+
- name: Create monitoring directory
|
|
7
|
+
file:
|
|
8
|
+
path: /opt/monitoring
|
|
9
|
+
state: directory
|
|
10
|
+
|
|
11
|
+
- name: Create docker-compose.yml for monitoring
|
|
12
|
+
copy:
|
|
13
|
+
dest: /opt/monitoring/docker-compose.yml
|
|
14
|
+
content: |
|
|
15
|
+
version: '3'
|
|
16
|
+
services:
|
|
17
|
+
prometheus:
|
|
18
|
+
image: prom/prometheus
|
|
19
|
+
ports:
|
|
20
|
+
- 9090:9090
|
|
21
|
+
volumes:
|
|
22
|
+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
|
23
|
+
grafana:
|
|
24
|
+
image: grafana/grafana
|
|
25
|
+
ports:
|
|
26
|
+
- 3000:3000
|
|
27
|
+
|
|
28
|
+
- name: Create prometheus config
|
|
29
|
+
copy:
|
|
30
|
+
dest: /opt/monitoring/prometheus.yml
|
|
31
|
+
content: |
|
|
32
|
+
global:
|
|
33
|
+
scrape_interval: 15s
|
|
34
|
+
scrape_configs:
|
|
35
|
+
- job_name: 'prometheus'
|
|
36
|
+
static_configs:
|
|
37
|
+
- targets: ['localhost:9090']
|
|
38
|
+
|
|
39
|
+
- name: Start monitoring services
|
|
40
|
+
command: docker compose up -d
|
|
41
|
+
args:
|
|
42
|
+
chdir: /opt/monitoring
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
- name: Project Service Playbook
|
|
2
|
+
block:
|
|
3
|
+
- name: Set systemd service unit variables
|
|
4
|
+
set_fact:
|
|
5
|
+
systemd_unit_name: "{{ project_name }}-{{ branch_name }}.service"
|
|
6
|
+
systemd_unit_path: "/etc/systemd/system/{{ systemd_unit_name }}.service"
|
|
7
|
+
|
|
8
|
+
- name: Create Docker Service
|
|
9
|
+
include_tasks: docker/create_docker_service.yml
|
|
10
|
+
|
|
11
|
+
- name: Enable and start service
|
|
12
|
+
ansible.builtin.systemd:
|
|
13
|
+
name: "{{ systemd_unit_name }}"
|
|
14
|
+
state: started
|
|
15
|
+
enabled: yes
|
|
16
|
+
become: yes
|
|
17
|
+
ignore_errors: yes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
- name: Push Code Playbook
|
|
2
|
+
block:
|
|
3
|
+
- name: Ensure project directory exists
|
|
4
|
+
file:
|
|
5
|
+
path: "{{ project_dest_dir }}"
|
|
6
|
+
state: directory
|
|
7
|
+
mode: '0755'
|
|
8
|
+
|
|
9
|
+
- name: Copy project files to target
|
|
10
|
+
copy:
|
|
11
|
+
src: "{{ playbook_dir }}/../../"
|
|
12
|
+
dest: "{{ project_dest_dir }}/"
|
|
13
|
+
# Note: In ansible-runner, playbook_dir is inside private_data_dir/project/vm_setup.
|
|
14
|
+
# We need to be careful about the source path.
|
|
15
|
+
# However, ansible_runner isolates execution.
|
|
16
|
+
# Better approach: Pass SOURCE_PATH as extravar.
|
|
17
|
+
when: false # Placeholder, we will use synchronize or better strategy.
|
|
18
|
+
|
|
19
|
+
# Re-thinking: simple 'copy' of just the compose file is safer for now if we don't know build context.
|
|
20
|
+
# But usually context is needed.
|
|
21
|
+
# Let's rely on 'synchronize' (rsync) if available, or just copy the compose file if user only provided that.
|
|
22
|
+
|
|
23
|
+
# For MVP of 'deploy-docker', let's copy the DOCKER_COMPOSE_FILE_PATH and .env if exists.
|
|
24
|
+
- name: Copy Docker Compose file
|
|
25
|
+
copy:
|
|
26
|
+
src: "{{ SOURCE_PATH }}/{{ DOCKER_COMPOSE_FILE_PATH }}"
|
|
27
|
+
dest: "{{ project_dest_dir }}/{{ DOCKER_COMPOSE_FILE_PATH }}"
|
|
28
|
+
|
|
29
|
+
- name: Copy Env file
|
|
30
|
+
copy:
|
|
31
|
+
src: "{{ SOURCE_PATH }}/{{ ENV_FILE_PATH | default('.env') }}"
|
|
32
|
+
dest: "{{ project_dest_dir }}/{{ ENV_FILE_PATH | default('.env') }}"
|
|
33
|
+
failed_when: false
|
|
34
|
+
|
|
35
|
+
- name: Deploy application
|
|
36
|
+
shell: "{{ DEPLOY_COMMAND | default('docker-compose up -d --remove-orphans') }}"
|
|
37
|
+
args:
|
|
38
|
+
chdir: "{{ project_dest_dir }}"
|
|
39
|
+
environment:
|
|
40
|
+
GITHUB_REPOSITORY_OWNER: "{{ GITHUB_REPOSITORY_OWNER | default('') }}"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
- name: Setup VM
|
|
2
|
+
block:
|
|
3
|
+
# --- Extract Project Name from GITHUB_PROJECT_URL ---
|
|
4
|
+
- name: Extract project name from GITHUB_PROJECT_URL
|
|
5
|
+
set_fact:
|
|
6
|
+
project_name: "{{ GITHUB_PROJECT_URL | basename | regex_replace('\\.git$', '') }}"
|
|
7
|
+
|
|
8
|
+
# --- Set project_dest_dir based on EXECUTION_TYPE ---
|
|
9
|
+
- name: Set project_dest_dir variable for cloud
|
|
10
|
+
set_fact:
|
|
11
|
+
project_dest_dir: "{{ ansible_user_dir }}/{{ project_name }}"
|
|
12
|
+
when: EXECUTION_TYPE == "cloud"
|
|
13
|
+
|
|
14
|
+
- name: Set project_dest_dir variable for normal
|
|
15
|
+
set_fact:
|
|
16
|
+
project_dest_dir: "{{ playbook_dir }}/{{ project_name }}"
|
|
17
|
+
when: EXECUTION_TYPE == "normal"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Create environment file if env_path and env_data are provided
|
|
3
|
+
when: ENV_PATH is defined and ENV_DATA is defined and PROJECT_PATH is defined
|
|
4
|
+
copy:
|
|
5
|
+
dest: "{{ project_dest_dir }}/{{ ENV_PATH }}"
|
|
6
|
+
content: "{{ ENV_DATA | to_nice_yaml }}"
|
|
7
|
+
mode: '0644'
|
vm_tool/webhooks.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Webhook support for deployment notifications."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class WebhookSender:
|
|
14
|
+
"""Send webhook notifications for deployment events."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, webhook_url: Optional[str] = None):
|
|
17
|
+
self.webhook_url = webhook_url
|
|
18
|
+
|
|
19
|
+
def send(
|
|
20
|
+
self, event: str, data: Dict[str, Any], webhook_url: Optional[str] = None
|
|
21
|
+
) -> bool:
|
|
22
|
+
"""Send webhook notification.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
event: Event type (e.g., 'deployment.success', 'deployment.failed')
|
|
26
|
+
data: Event data
|
|
27
|
+
webhook_url: Override default webhook URL
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
True if webhook sent successfully, False otherwise
|
|
31
|
+
"""
|
|
32
|
+
url = webhook_url or self.webhook_url
|
|
33
|
+
if not url:
|
|
34
|
+
logger.warning("No webhook URL configured")
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
payload = {
|
|
38
|
+
"event": event,
|
|
39
|
+
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
40
|
+
"data": data,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
response = requests.post(
|
|
45
|
+
url,
|
|
46
|
+
json=payload,
|
|
47
|
+
headers={"Content-Type": "application/json"},
|
|
48
|
+
timeout=10,
|
|
49
|
+
)
|
|
50
|
+
response.raise_for_status()
|
|
51
|
+
logger.info(f"Webhook sent successfully: {event}")
|
|
52
|
+
return True
|
|
53
|
+
except requests.exceptions.RequestException as e:
|
|
54
|
+
logger.error(f"Failed to send webhook: {e}")
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
def deployment_started(self, host: str, **kwargs):
|
|
58
|
+
"""Send deployment started event."""
|
|
59
|
+
return self.send("deployment.started", {"host": host, **kwargs})
|
|
60
|
+
|
|
61
|
+
def deployment_success(self, host: str, duration: float, **kwargs):
|
|
62
|
+
"""Send deployment success event."""
|
|
63
|
+
return self.send(
|
|
64
|
+
"deployment.success", {"host": host, "duration_seconds": duration, **kwargs}
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def deployment_failed(self, host: str, error: str, **kwargs):
|
|
68
|
+
"""Send deployment failed event."""
|
|
69
|
+
return self.send("deployment.failed", {"host": host, "error": error, **kwargs})
|
|
70
|
+
|
|
71
|
+
def rollback_started(self, host: str, **kwargs):
|
|
72
|
+
"""Send rollback started event."""
|
|
73
|
+
return self.send("rollback.started", {"host": host, **kwargs})
|
|
74
|
+
|
|
75
|
+
def rollback_success(self, host: str, **kwargs):
|
|
76
|
+
"""Send rollback success event."""
|
|
77
|
+
return self.send("rollback.success", {"host": host, **kwargs})
|
|
78
|
+
|
|
79
|
+
def health_check_failed(self, host: str, check_type: str, **kwargs):
|
|
80
|
+
"""Send health check failed event."""
|
|
81
|
+
return self.send(
|
|
82
|
+
"health_check.failed", {"host": host, "check_type": check_type, **kwargs}
|
|
83
|
+
)
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vm_tool
|
|
3
|
+
Version: 1.0.32
|
|
4
|
+
Summary: A Comprehensive Tool for Setting Up Virtual Machines.
|
|
5
|
+
Home-page: https://github.com/thesunnysinha/vm_tool
|
|
6
|
+
Author: Sunny Sinha
|
|
7
|
+
Author-email: Sunny Sinha <thesunnysinha@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Documentation, https://vm-tool.sunnysinha.online/
|
|
10
|
+
Project-URL: Source, https://github.com/thesunnysinha/vm_tool
|
|
11
|
+
Project-URL: Tracker, https://github.com/thesunnysinha/vm_tool/issues
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
22
|
+
Classifier: Topic :: System :: Systems Administration
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: ansible
|
|
27
|
+
Requires-Dist: ansible-runner
|
|
28
|
+
Requires-Dist: paramiko
|
|
29
|
+
Requires-Dist: pydantic
|
|
30
|
+
Requires-Dist: pyyaml
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=6.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: check-manifest; extra == "dev"
|
|
34
|
+
Requires-Dist: twine; extra == "dev"
|
|
35
|
+
Requires-Dist: wheel; extra == "dev"
|
|
36
|
+
Requires-Dist: bump-my-version; extra == "dev"
|
|
37
|
+
Requires-Dist: bandit; extra == "dev"
|
|
38
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
39
|
+
Requires-Dist: mkdocs-material; extra == "dev"
|
|
40
|
+
Requires-Dist: mkdocstrings[python]; extra == "dev"
|
|
41
|
+
Requires-Dist: black; extra == "dev"
|
|
42
|
+
Requires-Dist: isort; extra == "dev"
|
|
43
|
+
Dynamic: author
|
|
44
|
+
Dynamic: home-page
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
Dynamic: requires-python
|
|
47
|
+
|
|
48
|
+
# 🚀 VM Setup Tool
|
|
49
|
+
|
|
50
|
+
[](https://pypi.org/project/vm-tool/) [](https://pypi.org/project/vm-tool/)
|
|
51
|
+
|
|
52
|
+
[**Documentation**](https://vm-tool.sunnysinha.online/) • [**PyPI**](https://pypi.org/project/vm-tool/) • [**GitHub**](https://github.com/thesunnysinha/vm_tool) • [**Contributing**](CONTRIBUTING) • [**License**](LICENSE)
|
|
53
|
+
|
|
54
|
+
A modern, user-friendly solution for automating and managing virtual machine (VM) setup and configuration using Ansible.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## ✨ Features
|
|
59
|
+
|
|
60
|
+
- Automated VM setup with Docker & Docker Compose
|
|
61
|
+
- Cloud VM provisioning via SSH
|
|
62
|
+
- **Infrastructure Provisioning**: Terraform integration for cloud providers (AWS, etc.)
|
|
63
|
+
- **Kubernetes Ready**: One-click K3s cluster setup
|
|
64
|
+
- **Observability**: Instant Prometheus & Grafana deployment
|
|
65
|
+
- **CI/CD Pipelines**: Auto-generate GitHub Actions workflows
|
|
66
|
+
- SSH key management and configuration
|
|
67
|
+
- Simple Python API for integration
|
|
68
|
+
- One-command version check: `vm_tool --version`
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## ⚡️ Installation
|
|
73
|
+
|
|
74
|
+
Install the latest version from PyPI:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install vm-tool
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🛠️ Usage Examples
|
|
83
|
+
|
|
84
|
+
### 🚀 Universal Deployment (CLI)
|
|
85
|
+
|
|
86
|
+
#### 1. Generate CI/CD Pipeline
|
|
87
|
+
|
|
88
|
+
Bootstrap your project with a complete GitHub Actions workflow:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
vm_tool generate-pipeline
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### 2. Provision Infrastructure
|
|
95
|
+
|
|
96
|
+
Provision cloud resources using Terraform (requires Terraform installed):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
vm_tool provision --provider aws --action apply --vars region=us-east-1
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### 3. Setup Kubernetes (K3s)
|
|
103
|
+
|
|
104
|
+
Deploy a lightweight Kubernetes cluster to your servers:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
vm_tool setup-k8s --inventory inventory.yml
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### 4. Setup Observability
|
|
111
|
+
|
|
112
|
+
Deploy Prometheus and Grafana for instant monitoring:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
vm_tool setup-monitoring --inventory inventory.yml
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 🐍 Python API Usage
|
|
119
|
+
|
|
120
|
+
#### Automated Local VM Setup
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from vm_tool.runner import SetupRunner, SetupRunnerConfig
|
|
124
|
+
|
|
125
|
+
config = SetupRunnerConfig(
|
|
126
|
+
github_username='your_github_username',
|
|
127
|
+
github_token='your_github_token',
|
|
128
|
+
github_project_url='your_github_project_url',
|
|
129
|
+
github_branch='your_branch_name',
|
|
130
|
+
docker_compose_file_path='path_to_your_docker_compose_file',
|
|
131
|
+
dockerhub_username='your_dockerhub_username',
|
|
132
|
+
dockerhub_password='your_dockerhub_password'
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
runner = SetupRunner(config)
|
|
136
|
+
runner.run_setup()
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Cloud VM Setup (via SSH)
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from vm_tool.runner import SetupRunner, SetupRunnerConfig, SSHConfig
|
|
143
|
+
|
|
144
|
+
config = SetupRunnerConfig(
|
|
145
|
+
github_username='your_github_username',
|
|
146
|
+
github_token='your_github_token',
|
|
147
|
+
github_project_url='your_github_project_url',
|
|
148
|
+
github_branch='your_branch_name',
|
|
149
|
+
docker_compose_file_path='path_to_your_docker_compose_file',
|
|
150
|
+
dockerhub_username='your_dockerhub_username',
|
|
151
|
+
dockerhub_password='your_dockerhub_password'
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
runner = SetupRunner(config)
|
|
155
|
+
|
|
156
|
+
ssh_configs = [
|
|
157
|
+
SSHConfig(
|
|
158
|
+
ssh_username='your_ssh_username',
|
|
159
|
+
ssh_password='your_ssh_password',
|
|
160
|
+
ssh_hostname='your_ssh_hostname',
|
|
161
|
+
ssh_identity_file='/path/to/your/ssh_key' # Optional
|
|
162
|
+
)
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
runner.run_cloud_setup(ssh_configs)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### SSH Key Management
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from vm_tool.ssh import SSHSetup
|
|
172
|
+
|
|
173
|
+
ssh_setup = SSHSetup(
|
|
174
|
+
hostname='your_vm_hostname',
|
|
175
|
+
username='your_vm_username',
|
|
176
|
+
password='your_vm_password',
|
|
177
|
+
email='your_email_for_ssh_key'
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
ssh_setup.setup()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 🖥️ Command Line Version Check
|
|
186
|
+
|
|
187
|
+
Check your installed version at any time:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
vm_tool --version
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## ⚙️ Configuration Options
|
|
196
|
+
|
|
197
|
+
- `github_username`: GitHub username (for private repos)
|
|
198
|
+
- `github_token`: GitHub token (for private repos)
|
|
199
|
+
- `github_project_url`: GitHub repository URL
|
|
200
|
+
- `github_branch`: Branch to use (default: main)
|
|
201
|
+
- `docker_compose_file_path`: Path to Docker Compose file (default: docker-compose.yml)
|
|
202
|
+
- `dockerhub_username`: Docker Hub username (if login needed)
|
|
203
|
+
- `dockerhub_password`: Docker Hub password (if login needed)
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 📚 Learn More
|
|
208
|
+
|
|
209
|
+
See the [Official Documentation](https://vm-tool.sunnysinha.online/) for complete guides. Visit the [PyPI page](https://pypi.org/project/vm-tool/) for generic details, or the [GitHub repository](https://github.com/thesunnysinha/vm_tool) for code and issues.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
Empower your infrastructure automation with **VM Setup Tool** – fast, reliable, and developer-friendly!
|