Initial Tasks:
โ
Task 1: Set up a virtual environment (venv) and install the required packages (pip install flask django requests logging).
python3 -m venv venv
source venv/bin/activate
pip install flask django requests logging
๐น Challenge 1: Create a Python script that connects to a remote server via SSH using paramiko.
Solution:
import paramiko
def ssh_connect(host, username, password, command):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username=username, password=password)
stdin, stdout, stderr = client.exec_command(command)
print(stdout.read().decode())
client.close()
ssh_connect("your_server_ip", "your_user", "your_password", "ls -l")
Explanation:
Uses
paramikoto connect to a remote server.Executes a command (
ls -l) and prints the output.
๐น Challenge 2: Build a simple Flask API with an endpoint that returns system health (CPU/memory usage).
Solution:
from flask import Flask, jsonify
import psutil
app = Flask(__name__)
@app.route('/health')
def system_health():
return jsonify({
"cpu_usage": psutil.cpu_percent(),
"memory_usage": psutil.virtual_memory().percent
})
if __name__ == '__main__':
app.run(debug=True)
Explanation:
- A Flask API that returns CPU and memory usage using
psutil.
๐น Challenge 4: Use Python subprocess to execute system commands and capture output.
Solution:
import subprocess
def run_command(command):
"""Executes a system command and captures the output."""
try:
result = subprocess.run(command, shell=True, text=True, capture_output=True, check=True)
print("Output:\n", result.stdout)
except subprocess.CalledProcessError as e:
print("Error:\n", e.stderr)
# Example: List files in the current directory
run_command("ls -l") # Use "dir" instead of "ls -l" on Windows
Explanation:
Uses
subprocess.run()to execute system commands.shell=Trueallows running shell commands directly.capture_output=Truestores both stdout and stderr.check=Trueraises an error if the command fails.
๐น Challenge 5: Build a Flask API that fetches live weather data from an external API and returns it in JSON format.
Solution:
import requests
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/weather/<city>')
def get_weather(city):
api_key = "your_api_key"
url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
response = requests.get(url).json()
return jsonify(response)
if __name__ == '__main__':
app.run(debug=True)
Explanation:
- Calls OpenWeatherMap API and returns weather data for a given city.
๐น Challenge 6: Deploy a Django application on AWS EC2 with Nginx & Gunicorn.
Solution (Steps):
- Launch EC2 instance.
- Install dependencies:
sudo apt update && sudo apt install python3-pip python3-venv nginx
- Setup Django project:
python3 -m venv venv
source venv/bin/activate
pip install django gunicorn
django-admin startproject myproject
- Run Gunicorn:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
- Configure Nginx (/etc/nginx/sites-available/myproject):
server {
location / {
proxy_pass http://127.0.0.1:8000;
}
}
- Restart Nginx:
sudo systemctl restart nginx
Explanation:
- Deploys Django with Gunicorn and Nginx on AWS EC2.
๐น Challenge 7: Write a Python program to parse log files and extract failed SSH login attempts.
Solution:
def parse_failed_logins(log_file):
pattern = r"Failed password for (invalid user )?(\S+) from (\d+\.\d+\.\d+\.\d+)"
with open(log_file, 'r') as file:
for line in file:
match = re.search(pattern, line)
if match:
user = match.group(2)
ip = match.group(3)
print(f"Failed login attempt - User: {user}, IP: {ip}")
# Run with:
parse_failed_logins("/var/log/auth.log")
Explanation:
- Reads logs and extracts failed SSH login attempts.
๐น Challenge 8: Use fabric or paramiko to automate SSH login and run commands on multiple servers.
Solution:
import paramiko
servers = [
{"host": "192.168.1.10", "user": "ubuntu", "key": "/path/to/private-key.pem"},
{"host": "192.168.1.20", "user": "ec2-user", "key": "/path/to/private-key.pem"}
]
def run_command(command):
for server in servers:
print(f"Connecting to {server['host']}...")
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=server["host"], username=server["user"], key_filename=server["key"])
stdin, stdout, stderr = client.exec_command(command)
print(f"Output from {server['host']}:\n{stdout.read().decode()}")
client.close() except Exception as e:
print(f"Error connecting to {server['host']}: {e}")
# Example usage
run_command("uptime")
Explanation:
- Uses Paramiko to run commands on remote servers.
๐น Challenge 9: Implement a Python script that monitors Docker containers and sends alerts if a container crashes.
Solution:
import docker
import time
import smtplib
from email.mime.text import MIMEText
# Docker client
client = docker.from_env()
# Email alert function
def send_email_alert(container_name):
sender_email = "your-email@gmail.com"
receiver_email = "alert-receiver@gmail.com"
password = "your-email-password"
msg = MIMEText(f"Alert: Container {container_name} has crashed!")
msg["Subject"] = "Docker Container Crash Alert"
msg["From"] = sender_email
msg["To"] = receiver_email
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, msg.as_string())
server.quit()
print(f"Email alert sent for {container_name}!")
except Exception as e:
print(f"Failed to send email: {e}")
# Monitor Docker containers
def monitor_containers():
running_containers = {c.id: c.name for c in client.containers.list()}
while True:
time.sleep(5) # Check every 5 seconds
for container_id, container_name in running_containers.items():
try:
container = client.containers.get(container_id)
if container.status != "running":
print(f"ALERT: {container_name} has crashed!")
send_email_alert(container_name)
except docker.errors.NotFound:
print(f"ALERT: {container_name} has been removed or crashed!")
send_email_alert(container_name)
if __name__ == "__main__":
print("Starting Docker container monitoring...")
monitor_containers()
Explanation:
Monitors all running containers
Detects crashes in real-time
Sends alerts via Email
Runs in a continuous loop
๐น Challenge 10: Check GitHub Repo for New Commits & Trigger Build
Solution:
import requests
import time
# GitHub Repo Details
GITHUB_REPO = "owner/repository" # Replace with your repo
GITHUB_BRANCH = "main" # Change based on your workflow
GITHUB_TOKEN = "your_github_token" # Required for private repos
# Jenkins Build Details
JENKINS_URL = "http://your-jenkins-server/job/your-job/build"
JENKINS_USER = "your_username"
JENKINS_API_TOKEN = "your_jenkins_api_token"
# Headers for GitHub API
HEADERS = {"Authorization": f"token {GITHUB_TOKEN}"} if GITHUB_TOKEN else {}
def get_latest_commit():
"""Fetches the latest commit SHA from GitHub."""
url = f"https://api.github.com/repos/{GITHUB_REPO}/commits/{GITHUB_BRANCH}"
response = requests.get(url, headers=HEADERS)
if response.status_code == 200:
return response.json()["sha"]
else:
print(f"Error fetching commits: {response.json()}")
return None
def trigger_jenkins_build():
"""Triggers a Jenkins build job."""
response = requests.post(JENKINS_URL, auth=(JENKINS_USER, JENKINS_API_TOKEN))
if response.status_code == 201:
print("โ
Jenkins build triggered successfully!")
else:
print(f"โ ๏ธ Failed to trigger build: {response.text}")
def monitor_commits():
"""Continuously checks for new commits and triggers a build."""
last_commit = get_latest_commit()
if not last_commit:
print("Failed to fetch initial commit. Exiting...")
return
print(f"Monitoring repository: {GITHUB_REPO} on branch: {GITHUB_BRANCH}")
while True:
time.sleep(60) # Check every 60 seconds
new_commit = get_latest_commit()
if new_commit and new_commit != last_commit:
print(f"๐ New commit detected: {new_commit}")
trigger_jenkins_build()
last_commit = new_commit
if __name__ == "__main__":
monitor_commits()
Explanation:
Uses the GitHub API to fetch the latest commit hash from a specified branch.
Continuously monitors the repository for new commits.
If a new commit is detected, it triggers a Jenkins build using the Jenkins API.
Runs in a loop checking every 60 seconds for updates.
๐น Challenge 11: Package Python Script as CLI Tool
Solution (script.py):
import argparse
parser = argparse.ArgumentParser(description="Simple CLI tool")
parser.add_argument("--name", required=True, help="Enter your name")
args = parser.parse_args()
print(f"Hello, {args.name}!")
Run:
python script.py --name Pratik
Explanation:
- Uses
argparseto create a simple CLI tool.
๐น Challenge 12: Convert Python Script to Binary (PyInstaller)
Solution:
pip install pyinstaller
pyinstaller --onefile --noconsole script.py
Explanation:
PyInstaller converts the Python script into a standalone binary executable.
The
--onefileflag creates a single executable instead of multiple files.The
--noconsoleflag (optional) hides the console when running GUI applications.The generated binary does not require Python on the target system.