diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..09e8e0c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,17 @@ +name: Validate Shell Script + +on: [push] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Validate Shell Script + run: | + # Install shellcheck + sudo apt-get update + sudo apt-get install -y shellcheck + # Run shellcheck on the script + shellcheck environment_setup.sh + shellcheck performance-monitoring.sh diff --git a/101daysofdevops/Day3/search_for_file_v1.py b/101daysofdevops/Day3/search_for_file_v1.py new file mode 100644 index 0000000..4c8691d --- /dev/null +++ b/101daysofdevops/Day3/search_for_file_v1.py @@ -0,0 +1,7 @@ +import os + +for dirpath, dirname, filename in os.walk("/etc"): + for file in filename: + comp_path= os.path.join(dirpath,file) + if file == "hosts": + print(comp_path) diff --git a/101daysofdevops/Day3/search_for_file_v2.py b/101daysofdevops/Day3/search_for_file_v2.py new file mode 100644 index 0000000..8f1ef4c --- /dev/null +++ b/101daysofdevops/Day3/search_for_file_v2.py @@ -0,0 +1,15 @@ +import os +import argparse + +my_parser = argparse.ArgumentParser(description='Reading the directory path to find the file') +my_parser.add_argument("--p","--pathname", + help='Please enter the directory path ') +my_parser.add_argument("--f","--filesearch", + help='Please enter the filename to search') +args = my_parser.parse_args() + +for dirpath, dirname, filename in os.walk(args.pathname): + for file in filename: + comp_path= os.path.join(dirpath,file) + if file == args.filesearch: + print(comp_path) diff --git a/101daysofdevops/Day4/search_for_file_greater_then_Xdays_v1v1.py b/101daysofdevops/Day4/search_for_file_greater_then_Xdays_v1v1.py new file mode 100644 index 0000000..9e5fcb1 --- /dev/null +++ b/101daysofdevops/Day4/search_for_file_greater_then_Xdays_v1v1.py @@ -0,0 +1,13 @@ +import os +import datetime + +file_age=15 +today_date=datetime.datetime.now() + +for dir,dirpath,filename in os.walk("/var/log"): + for file in filename: + complete_path=os.path.join(dir,file) + file_creation_time=datetime.datetime.fromtimestamp(os.path.getctime(complete_path)) + time_diff=(today_date-file_creation_time).days + if time_diff> file_age: + print(complete_path, time_diff) diff --git a/101daysofdevops/Day4/search_for_file_greater_then_Xdays_v2.py b/101daysofdevops/Day4/search_for_file_greater_then_Xdays_v2.py new file mode 100644 index 0000000..2612e0e --- /dev/null +++ b/101daysofdevops/Day4/search_for_file_greater_then_Xdays_v2.py @@ -0,0 +1,18 @@ +import os +import datetime + +file_age=15 + +def days_creation(file_creation_time): + today_date = datetime.datetime.now() + time_diff = (today_date - file_creation_time).days + return time_diff + + +for dir,dirpath,filename in os.walk("/var/log"): + for file in filename: + complete_path=os.path.join(dir,file) + file_creation_time=datetime.datetime.fromtimestamp(os.path.getctime(complete_path)) + time_diff = days_creation(file_creation_time) + if time_diff> file_age: + print(complete_path, time_diff) diff --git a/101daysofdevops/Day5/check_file_with_specific_extension_and_file_size.py b/101daysofdevops/Day5/check_file_with_specific_extension_and_file_size.py new file mode 100644 index 0000000..a60b2a9 --- /dev/null +++ b/101daysofdevops/Day5/check_file_with_specific_extension_and_file_size.py @@ -0,0 +1,9 @@ +import os + +for dirpath, dirname, filename in os.walk("/etc/openldap"): + for file in filename: + comp_path= os.path.join(dirpath,file) + if file.endswith(".conf"): + print(comp_path) + file_size = os.path.getsize(comp_path) + print("File size is: ", file_size, "bytes") diff --git a/101daysofdevops/Readme.md b/101daysofdevops/Readme.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/101daysofdevops/Readme.md @@ -0,0 +1 @@ + diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 97f3ccd..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,80 +0,0 @@ -pipeline { - agent any - tools { - "org.jenkinsci.plugins.terraform.TerraformInstallation" "terraform-0.11.8" - } - parameters { - string(name: 'WORKSPACE', defaultValue: 'development', description:'setting up workspace for terraform') - } - environment { - TF_HOME = tool('terraform-0.11.8') - TF_IN_AUTOMATION = "true" - PATH = "$TF_HOME:$PATH" - ACCESS_KEY = credentials('AWS_ACCESS_KEY_ID') - SECRET_KEY = credentials('AWS_SECRET_ACCESS_KEY') - } - stages { - stage('TerraformInit'){ - steps { - dir('ec2_pipeline/'){ - sh "terraform init -input=false" - sh "echo \$PWD" - sh "whoami" - } - } - } - - stage('TerraformFormat'){ - steps { - dir('ec2_pipeline/'){ - sh "terraform fmt -list=true -write=false -diff=true -check=true" - } - } - } - - stage('TerraformValidate'){ - steps { - dir('ec2_pipeline/'){ - sh "terraform validate" - } - } - } - - stage('TerraformPlan'){ - steps { - dir('ec2_pipeline/'){ - script { - try { - sh "terraform workspace new ${params.WORKSPACE}" - } catch (err) { - sh "terraform workspace select ${params.WORKSPACE}" - } - sh "terraform plan -var 'access_key=$AWS_ACCESS_KEY_ID' -var 'secret_key=$AWS_SECRET_ACCESS_KEY' \ - -var-file 'terraform.tfvars' -out terraform.tfplan;echo \$? > status" - stash name: "terraform-plan", includes: "terraform.tfplan" - } - } - } - } - stage('TerraformApply'){ - steps { - script{ - def apply = false - try { - input message: 'Can you please confirm the apply', ok: 'Ready to Apply the Config' - apply = true - } catch (err) { - apply = false - currentBuild.result = 'UNSTABLE' - } - if(apply){ - dir('ec2_pipeline/'){ - unstash "terraform-plan" - sh 'terraform apply terraform.tfplan' - } - } - } - } - } - } -} \ No newline at end of file diff --git a/Kubernetes-and-Cloud-Native-Associate/README.md b/Kubernetes-and-Cloud-Native-Associate/README.md new file mode 100644 index 0000000..b059144 --- /dev/null +++ b/Kubernetes-and-Cloud-Native-Associate/README.md @@ -0,0 +1 @@ +# Kubernetes and Cloud Native Associate (KCNA) diff --git a/README.md b/README.md index e9d4725..3606811 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# 100daysofdevops +# 100daysofdevops -AWS +#AWS Day 1-Introduction to CloudWatch Metrics https://medium.com/faun/100-days-of-devops-day-1-introduction-to-cloudwatch-metrics-b04be36307a8 diff --git a/apache_log_parsing/apache_log_parsing_v1.py b/apache_log_parsing/apache_log_parsing_v1.py new file mode 100644 index 0000000..a309534 --- /dev/null +++ b/apache_log_parsing/apache_log_parsing_v1.py @@ -0,0 +1,20 @@ +import re +from collections import Counter +import csv +import argparse + +my_parser = argparse.ArgumentParser(description='Reading the log file') +my_parser.add_argument("--l","--logfile", + help='Please enter the logfile to parse',dest="logfile",type=argparse.FileType('r'), required=True) +args = my_parser.parse_args() + + +logreg="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" +with args.logfile as f: + fread = f.read() + ip_list = re.findall(logreg, fread) + with open("ipnewcount.csv", "w") as f: + fwritercsv = csv.writer(f) + fwritercsv.writerow(["IP_Address", "Count"]) + for k, v in Counter(ip_list).items(): + fwritercsv.writerow([k, v]) diff --git a/apache_log_parsing/apache_log_parsing_v2.py b/apache_log_parsing/apache_log_parsing_v2.py new file mode 100644 index 0000000..e87f49a --- /dev/null +++ b/apache_log_parsing/apache_log_parsing_v2.py @@ -0,0 +1,38 @@ +import re +from collections import Counter +import csv +import argparse + + +logreg="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" + +# Create the parser +my_parser = argparse.ArgumentParser(description='Reading the log and csv file') +my_parser.add_argument("--l","--logfile", + help='Please enter the logfile to parse',dest="logfile",type=argparse.FileType('r'), required=True) +args = my_parser.parse_args() + + +def read_file(logfile): + with args.logfile as f: + log = f.read() + ip_list = re.findall(logreg,log) + return ip_list + +def read_count(): + ip_list = read_file(args.logfile) + ip_count = Counter(ip_list) + return ip_count.items() + + +def csv_write(): + counter = read_count() + with open("ip_count.csv",'w') as f: + fwriter = csv.writer(f) + + fwriter.writerow(["IP_Address","Count"]) + for item,val in counter: + fwriter.writerow([item, val]) + +if __name__ == '__main__': + csv_write() diff --git a/apache_log_parsing/apache_log_parsing_v3.py b/apache_log_parsing/apache_log_parsing_v3.py new file mode 100644 index 0000000..9246e99 --- /dev/null +++ b/apache_log_parsing/apache_log_parsing_v3.py @@ -0,0 +1,48 @@ +import re +import csv +import argparse +from collections import Counter + +IP_REGEX = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" + +# Create the parser +parser = argparse.ArgumentParser(description='Reading the log and CSV file') +parser.add_argument("--l", "--logfile", + help='Please enter the logfile to parse', + dest="logfile", + type=argparse.FileType('r'), + required=True) + +def extract_ips(logfile): + """Extracts all IP addresses from the given logfile.""" + try: + with open(logfile, 'r') as f: + log = f.read() + except Exception as e: + print(f"Error reading file: {e}") + return [] + return re.findall(IP_REGEX, log) + +def count_ips(ip_list): + """Count the occurrence of each IP address in the list.""" + return Counter(ip_list) + +def write_csv(counter): + """Write the counter data to a CSV file.""" + try: + with open("ip_count.csv", 'w') as f: + writer = csv.DictWriter(f, fieldnames=["IP_Address", "Count"]) + writer.writeheader() + for item, count in counter.items(): + writer.writerow({"IP_Address": item, "Count": count}) + except Exception as e: + print(f"Error writing CSV file: {e}") + +def main(): + args = parser.parse_args() + ip_list = extract_ips(args.logfile) + ip_counter = count_ips(ip_list) + write_csv(ip_counter) + +if __name__ == '__main__': + main() diff --git a/apache_log_parsing/apache_log_parsing_v4.py b/apache_log_parsing/apache_log_parsing_v4.py new file mode 100644 index 0000000..211521f --- /dev/null +++ b/apache_log_parsing/apache_log_parsing_v4.py @@ -0,0 +1,45 @@ +import re +import csv +import argparse +from collections import Counter + +IP_REGEX = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" + +# Create the parser +parser = argparse.ArgumentParser(description='Parse a log file and output IP address occurrences to a CSV file.') +parser.add_argument("--l", "--logfile", + help='Logfile to parse', + dest="logfile", + type=argparse.FileType('r'), + required=True) +parser.add_argument("--o", "--output", + help='Output CSV file name', + dest="outputfile", + type=str, + default="ip_count.csv") + +def extract_ips(logfile): + """Extracts all IP addresses from the given logfile.""" + return re.findall(IP_REGEX, logfile.read()) + +def count_ips(ip_list): + """Count the occurrence of each IP address in the list.""" + return Counter(ip_list) + +def write_csv(counter, filename): + """Write the counter data to a CSV file.""" + with open(filename, 'w', newline='') as f: + writer = csv.DictWriter(f, fieldnames=["IP_Address", "Count"]) + writer.writeheader() + for item, count in counter.items(): + writer.writerow({"IP_Address": item, "Count": count}) + print(f"IP counts written to {filename}") + +def main(): + args = parser.parse_args() + ip_list = extract_ips(args.logfile) + ip_counter = count_ips(ip_list) + write_csv(ip_counter, args.outputfile) + +if __name__ == '__main__': + main() diff --git a/argocd_demo/yamls/deployment.yaml b/argocd_demo/yamls/deployment.yaml new file mode 100644 index 0000000..c0dded0 --- /dev/null +++ b/argocd_demo/yamls/deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app: my-nginx + name: my-nginx +spec: + replicas: 3 + selector: + matchLabels: + app: my-nginx + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: my-nginx + spec: + containers: + - image: nginx + name: nginx + resources: {} +status: {} diff --git a/argocd_demo/yamls/service.yaml b/argocd_demo/yamls/service.yaml new file mode 100644 index 0000000..5f724d5 --- /dev/null +++ b/argocd_demo/yamls/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-nginx-service +spec: + type: NodePort + selector: + app: nginx + ports: + - port: 80 + targetPort: 80 + nodePort: 30007 diff --git a/aws-lambda/ec2_stop_start_instances/Role-Trust-Policy.json b/aws-lambda/ec2_stop_start_instances/Role-Trust-Policy.json new file mode 100644 index 0000000..87c7d7c --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances/Role-Trust-Policy.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} diff --git a/aws-lambda/ec2_stop_start_instances/ec2_stop1.py b/aws-lambda/ec2_stop_start_instances/ec2_stop1.py new file mode 100644 index 0000000..65b50d3 --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances/ec2_stop1.py @@ -0,0 +1,6 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +for instance in ec2.instances.all(): + instance.stop() diff --git a/aws-lambda/ec2_stop_start_instances/ec2_stop2-1.py b/aws-lambda/ec2_stop_start_instances/ec2_stop2-1.py new file mode 100644 index 0000000..d62a99e --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances/ec2_stop2-1.py @@ -0,0 +1,8 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +ec2_instance = {"Name": "instance-type", "Values": ["t2.micro"]} + +for instance in ec2.instances.filter(Filters=[ec2_instance]): + instance.stop() diff --git a/aws-lambda/ec2_stop_start_instances/ec2_stop2-2.py b/aws-lambda/ec2_stop_start_instances/ec2_stop2-2.py new file mode 100644 index 0000000..7cd7d80 --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances/ec2_stop2-2.py @@ -0,0 +1,9 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +ec2_instance = {"Name": "instance-type", "Values": ["t2.micro"]} +ec2_tag = {"Name": "tag:Name", "Values": ["boto3-prod"]} + +for instance in ec2.instances.filter(Filters=[ec2_tag]): + instance.stop() diff --git a/aws-lambda/ec2_stop_start_instances/ec2_stop3.py b/aws-lambda/ec2_stop_start_instances/ec2_stop3.py new file mode 100644 index 0000000..a9bff6f --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances/ec2_stop3.py @@ -0,0 +1,21 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +regions = [] +for region in ec2.meta.client.describe_regions()['Regions']: + regions.append(region['RegionName']) + + +for region in regions: + ec2 = boto3.resource("ec2", region_name=region) + + print(“EC2 region is:", region) + + ec2_instance = {"Name": "instance-state-name", "Values": ["running"]} + + instances = ec2.instances.filter(Filters=[ec2_instance]) + + for instance in instances: + instance.stop() + print("The following EC2 instances is now in stopped state", instance.id) diff --git a/aws-lambda/ec2_stop_start_instances/iam_policy.json b/aws-lambda/ec2_stop_start_instances/iam_policy.json new file mode 100644 index 0000000..868d800 --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances/iam_policy.json @@ -0,0 +1,24 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": "arn:aws:logs:*:*:*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstances", + "ec2:DescribeRegions", + "ec2:StartInstances", + "ec2:StopInstances" + ], + "Resource": "*" + } + ] +} diff --git a/aws-lambda/ec2_stop_start_instances_updated/Role-Trust-Policy.json b/aws-lambda/ec2_stop_start_instances_updated/Role-Trust-Policy.json new file mode 100644 index 0000000..87c7d7c --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances_updated/Role-Trust-Policy.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} diff --git a/aws-lambda/ec2_stop_start_instances_updated/iam_policy.json b/aws-lambda/ec2_stop_start_instances_updated/iam_policy.json new file mode 100644 index 0000000..868d800 --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances_updated/iam_policy.json @@ -0,0 +1,24 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": "arn:aws:logs:*:*:*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstances", + "ec2:DescribeRegions", + "ec2:StartInstances", + "ec2:StopInstances" + ], + "Resource": "*" + } + ] +} diff --git a/aws-lambda/ec2_stop_start_instances_updated/lambda.py b/aws-lambda/ec2_stop_start_instances_updated/lambda.py new file mode 100644 index 0000000..3c5314c --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances_updated/lambda.py @@ -0,0 +1,23 @@ +import boto3 + +def lambda_handler(event, context): + ec2 = boto3.resource("ec2") + + regions = [] + for region in ec2.meta.client.describe_regions()['Regions']: + regions.append(region['RegionName']) + + for region in regions: + ec2 = boto3.resource("ec2", region_name=region) + + print("EC2 region is: ", region) + + ec2_instance = {"Name": "instance-state-name", "Values": ["running"]} + + instances = ec2.instances.filter(Filters=[ec2_instance]) + + for instance in instances: + instance.stop() + print("The following EC2 instances is now in stopped state", instance.id) + + diff --git a/aws-lambda/ec2_stop_start_instances_updated/lambda.zip b/aws-lambda/ec2_stop_start_instances_updated/lambda.zip new file mode 100644 index 0000000..39319b6 Binary files /dev/null and b/aws-lambda/ec2_stop_start_instances_updated/lambda.zip differ diff --git a/aws-lambda/ec2_stop_start_instances_updated/main.tf b/aws-lambda/ec2_stop_start_instances_updated/main.tf new file mode 100644 index 0000000..d96fa24 --- /dev/null +++ b/aws-lambda/ec2_stop_start_instances_updated/main.tf @@ -0,0 +1,91 @@ +provider "aws" { + region = "us-west-2" +} + +resource "aws_iam_role" "lambda-role" { + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Sid = "" + Principal = { + Service = "lambda.amazonaws.com" + } + }, + ] + }) + tags = { + Name = "lambda-ec2-role" + } +} + +resource "aws_iam_policy" "lambda-policy" { + name = "lambda-ec2-stop-start" + + policy = jsonencode({ + Version = "2012-10-17" + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": "arn:aws:logs:*:*:*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstances", + "ec2:DescribeRegions", + "ec2:StartInstances", + "ec2:StopInstances" + ], + "Resource": "*" + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "lambda-ec2-policy-attach" { + policy_arn = aws_iam_policy.lambda-policy.arn + role = aws_iam_role.lambda-role.name +} + +resource "aws_lambda_function" "ec2-stop-start" { + filename = "lambda.zip" + function_name = "lambda" + role = aws_iam_role.lambda-role.arn + handler = "lambda.lambda_handler" + + # The filebase64sha256() function is available in Terraform 0.11.12 and later + # For Terraform 0.11.11 and earlier, use the base64sha256() function and the file() function: + # source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}" + source_code_hash = filebase64sha256("lambda.zip") + + runtime = "python3.7" + timeout = 63 +} + +resource "aws_cloudwatch_event_rule" "ec2-rule" { + name = "ec2-rule" + description = "Trigger Stop Instance every 5 min" + schedule_expression = "rate(5 minutes)" +} + +resource "aws_cloudwatch_event_target" "lambda-func" { + rule = aws_cloudwatch_event_rule.ec2-rule.name + target_id = "lambda" + arn = aws_lambda_function.ec2-stop-start.arn +} + +resource "aws_lambda_permission" "allow_cloudwatch" { + statement_id = "AllowExecutionFromCloudWatch" + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.ec2-stop-start.function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.ec2-rule.arn +} \ No newline at end of file diff --git a/aws_resource_notification/aws_billing_per_resource.sh b/aws_resource_notification/aws_billing_per_resource.sh new file mode 100644 index 0000000..77db5de --- /dev/null +++ b/aws_resource_notification/aws_billing_per_resource.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Set the start and end dates for the time period of cost report +start_date=$(date +%Y-%m-01) +end_date=$(date -d "$(date +%Y-%m-01) +1 month -1 day" +%Y-%m-%d) + +# Get the cost and usage report by resource,the level of granularity (e.g., hourly, daily, or monthly). Check this doc for more info https://docs.aws.amazon.com/cli/latest/reference/ce/get-cost-and-usage.html +usage_report=$(aws ce get-cost-and-usage --time-period Start=$start_date,End=$end_date --granularity MONTHLY --metrics "BlendedCost" "UnblendedCost" "UsageQuantity" --group-by Type=DIMENSION,Key=SERVICE --query 'ResultsByTime[0].Groups') + +# Verify if the cost and usage report retrieval was successful +if [ -z "$usage_report" ]; then + echo "Error: To retrieve cost and usage information by resource." + exit 1 +fi + +# Format the usage and cost report by resource as a table +report_table=$(echo "$usage_report" | jq -r '.[] | [.Keys[0], .Metrics.BlendedCost.Amount, .Metrics.UnblendedCost.Amount, .Metrics.UsageQuantity.Amount] | @tsv' | column -t -s $'\t' | awk 'BEGIN { print "Resource\tBlendedCost\tUnblendedCost\tUsageQuantity" } { print }') + +# Check if the EC2 or S3 resource usage exceeds $5 +if echo "$report_table" | grep -E '(^AmazonEC2|^AmazonS3)' | awk -F '\t' '$2 > 5 || $3 > 5'; then + # Send an email with the cost and usage report by resource(Don't forget to verify the email address: https://docs.aws.amazon.com/cli/latest/reference/ses/send-email.html) + aws ses send-email --from "sender@example.com" --to "recipient@example.com" --subject "AWS cost and usage report for the month" --text "$(echo "$report_table")" +fi diff --git a/boto3/boto3_meta.py b/boto3/boto3_meta.py new file mode 100644 index 0000000..bfafdb3 --- /dev/null +++ b/boto3/boto3_meta.py @@ -0,0 +1,4 @@ +>>> import boto3 +>>> ec2 = boto3.resource("ec2") +>>> for region in ec2.meta.client.describe_regions()['Regions']: +... print(region['RegionName']) diff --git a/boto3/cleaning_old_ebs_vol/cleaning_old_ebs_vol.py b/boto3/cleaning_old_ebs_vol/cleaning_old_ebs_vol.py new file mode 100644 index 0000000..eed4e33 --- /dev/null +++ b/boto3/cleaning_old_ebs_vol/cleaning_old_ebs_vol.py @@ -0,0 +1,11 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +vol_status={"Name":"status","Values":["available"]} + +for vol in ec2.volumes.filter(Filters=[vol_status]): + vol_id = vol.id + volume = ec2.Volume(vol.id) + print("Cleanup EBS volume: ", vol_id) + volume.delete() diff --git a/boto3/cleanup_old_ami/cleanup_old_ami.py b/boto3/cleanup_old_ami/cleanup_old_ami.py new file mode 100644 index 0000000..778c2a5 --- /dev/null +++ b/boto3/cleanup_old_ami/cleanup_old_ami.py @@ -0,0 +1,18 @@ +import boto3 +from datetime import datetime +from dateutil.parser import parse + +current_date=datetime.now() + +client = boto3.client("ec2") + +my_ami = client.describe_images(Owners=['self'])['Images'] + +for ami in my_ami: + creation_date=ami['CreationDate'] + creation_date_parse=parse(creation_date).replace(tzinfo=None) + ami_id = ami['ImageId'] + diff_in_days = (current_date - creation_date_parse).days + print("Cleaning up all the AMI greater then 2 days old", ami_id) + if diff_in_days > 2: + client.deregister_image(ImageId=ami_id) diff --git a/boto3/cleanup_old_ami/cleanup_old_ami_v2.py b/boto3/cleanup_old_ami/cleanup_old_ami_v2.py new file mode 100644 index 0000000..10e5c8f --- /dev/null +++ b/boto3/cleanup_old_ami/cleanup_old_ami_v2.py @@ -0,0 +1,23 @@ +import boto3 +from operator import itemgetter + +# Define the maximum number of AMIs to keep +max_count = 5 + +# Connect to AWS using the default profile +ec2 = boto3.client('ec2') + +# Retrieve a list of all AMIs +response = ec2.describe_images(Owners=['self']) + +# Sort the list of AMIs by creation date in descending order +sorted_images = sorted(response['Images'], key=itemgetter('CreationDate'), reverse=True) + +# Loop through the list of AMIs and delete any that are beyond the max_count threshold +for index, image in enumerate(sorted_images): + if index >= max_count: + ec2.deregister_image(ImageId=image['ImageId']) + print(f"Deregistered AMI {image['ImageId']}") + else: + print(f"Keeping AMI {image['ImageId']}") + break diff --git a/boto3/cleanup_old_ami/cleanup_old_ami_v3.py b/boto3/cleanup_old_ami/cleanup_old_ami_v3.py new file mode 100644 index 0000000..471dbac --- /dev/null +++ b/boto3/cleanup_old_ami/cleanup_old_ami_v3.py @@ -0,0 +1,34 @@ +import boto3 +from datetime import datetime +from dateutil.parser import parse + +# Set the tag key and value to use for filtering AMIs +tag_key = "my-tag-key" +tag_value = "my-tag-value" + +# Set the maximum number of days to keep an AMI +max_age_days = 2 + +# Connect to EC2 using the default profile +client = boto3.client("ec2") + +# Get a list of all the AMIs with the specified tag +my_ami = client.describe_images( + Owners=["self"], + Filters=[ + { + "Name": f"tag:{tag_key}", + "Values": [tag_value] + } + ] +)["Images"] + +# Loop through the list of AMIs and delete any that are older than the maximum age +for ami in my_ami: + creation_date = parse(ami["CreationDate"]).replace(tzinfo=None) + ami_id = ami["ImageId"] + age_in_days = (datetime.now() - creation_date).days + print(f"Checking AMI {ami_id} with age {age_in_days} days") + if age_in_days > max_age_days: + client.deregister_image(ImageId=ami_id) + print(f"Deleted AMI {ami_id} with age {age_in_days} days") diff --git a/boto3/cleanup_old_ami/cleanup_old_ami_v4.py b/boto3/cleanup_old_ami/cleanup_old_ami_v4.py new file mode 100644 index 0000000..4fdc493 --- /dev/null +++ b/boto3/cleanup_old_ami/cleanup_old_ami_v4.py @@ -0,0 +1,39 @@ +import boto3 +from datetime import datetime +from dateutil.parser import parse + +# Set the tag key and value to use for filtering AMIs +tag_key = "my-tag-key" +tag_value = "my-tag-value" + +# Set the maximum number of days to keep an AMI +max_age_days = 2 + +# Set the list of regions to clean up AMIs +regions = ["us-west-1", "us-west-2", "us-east-1"] + +# Loop through each region and clean up AMIs +for region in regions: + # Connect to EC2 in the current region using the default profile + client = boto3.client("ec2", region_name=region) + + # Get a list of all the AMIs with the specified tag + my_ami = client.describe_images( + Owners=["self"], + Filters=[ + { + "Name": f"tag:{tag_key}", + "Values": [tag_value] + } + ] + )["Images"] + + # Loop through the list of AMIs and delete any that are older than the maximum age + for ami in my_ami: + creation_date = parse(ami["CreationDate"]).replace(tzinfo=None) + ami_id = ami["ImageId"] + age_in_days = (datetime.now() - creation_date).days + print(f"Checking AMI {ami_id} in region {region} with age {age_in_days} days") + if age_in_days > max_age_days: + client.deregister_image(ImageId=ami_id) + print(f"Deleted AMI {ami_id} in region {region} with age {age_in_days} days") diff --git a/boto3/create_snapshot/create_snapshot.py b/boto3/create_snapshot/create_snapshot.py new file mode 100644 index 0000000..7597d6c --- /dev/null +++ b/boto3/create_snapshot/create_snapshot.py @@ -0,0 +1,10 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +for vol in ec2.volumes.all(): + vol_id = vol.id + volume = ec2.Volume(vol.id) + desc = 'This is a snapshot of {}'.format(vol_id) + print("Creating Snapshot of the following Volume : ", vol_id) + volume.create_snapshot(Description=desc) diff --git a/boto3/ec2_client_waiter.py b/boto3/ec2_client_waiter.py new file mode 100644 index 0000000..e1ffa22 --- /dev/null +++ b/boto3/ec2_client_waiter.py @@ -0,0 +1,10 @@ +import boto3 + +ec2 = boto3.client("ec2") + +instance_id=input("Please enter the instance id: ") +print("Starting EC2 instance") +instance=ec2.start_instances(InstanceIds=[instance_id]) +waiter = ec2.get_waiter('instance_running') +waiter.wait(InstanceIds=[instance_id]) +print("Your instance is up and running" diff --git a/boto3/ec2_information/retrieve_information_about_ec2.py b/boto3/ec2_information/retrieve_information_about_ec2.py new file mode 100644 index 0000000..b4d1577 --- /dev/null +++ b/boto3/ec2_information/retrieve_information_about_ec2.py @@ -0,0 +1,11 @@ +import boto3 +import csv + +ec2 = boto3.resource('ec2') +instances = ec2.instances.all() + +with open('ec2-instances.csv', 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["Instance ID", "State", "AMI ID", "Platform", "Instance Type", "Public IPv4 Address"]) + for instance in instances: + writer.writerow([instance.id, instance.state['Name'], instance.image.id, instance.platform, instance.instance_type, instance.public_ip_address]) diff --git a/boto3/ec2_information/updating_tags.py b/boto3/ec2_information/updating_tags.py new file mode 100644 index 0000000..b041b07 --- /dev/null +++ b/boto3/ec2_information/updating_tags.py @@ -0,0 +1,25 @@ +import boto3 +import csv + +# Export list of EC2 instances to CSV file +ec2 = boto3.resource('ec2') +instances = ec2.instances.all() + +with open('ec2-instances.csv', 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["Instance ID", "Name"]) + for instance in instances: + writer.writerow([instance.id, instance.tags[0]['Value'] if instance.tags else ""]) + +# Manually update CSV file with new tag keys and values + + +# Import updated CSV file and update tags for each EC2 instance +with open('ec2-instances-tags.csv', 'r') as file: + reader = csv.reader(file) + next(reader) # skip header row + for row in reader: + instance_id = row[0] + tag_key = row[2] + tag_value = row[3] + ec2.create_tags(Resources=[instance_id], Tags=[{'Key': tag_key, 'Value': tag_value}]) diff --git a/boto3/ec2_resource_client_waiter.py b/boto3/ec2_resource_client_waiter.py new file mode 100644 index 0000000..367cb37 --- /dev/null +++ b/boto3/ec2_resource_client_waiter.py @@ -0,0 +1,12 @@ +import boto3 + +ec2 = boto3.resource("ec2") +ec2_cli = boto3.client("ec2") + +instance_id=input("Please enter the instance id: ") +instance=ec2.Instance(instance_id) +print("Starting EC2 instance") +instance.start() +waiter = ec2_cli.get_waiter('instance_running') +waiter.wait(InstanceIds=[instance_id]) +print("Your instance is up and running") diff --git a/boto3/ec2_resource_waiter.py b/boto3/ec2_resource_waiter.py new file mode 100644 index 0000000..ff2e987 --- /dev/null +++ b/boto3/ec2_resource_waiter.py @@ -0,0 +1,10 @@ +import boto3 + +ec2 = boto3.resource("ec2") + +instance_id=input("Please enter the instance id: ") +instance=ec2.Instance(instance_id) +print("Starting EC2 instance") +instance.start() +instance.wait_until_running() +print("Your instance is up and running") diff --git a/boto3/listing_iam_user_paginator.py b/boto3/listing_iam_user_paginator.py new file mode 100644 index 0000000..e3aa2ae --- /dev/null +++ b/boto3/listing_iam_user_paginator.py @@ -0,0 +1,10 @@ +import boto3 + +iam_client = boto3.client("iam") +paginator = iam_client.get_paginator('list_users') +page_iterator=paginator.paginate() +count=1 +for user in page_iterator: + for username in user['Users']: + print(count, username['UserName']) + count+=1 diff --git a/boto3/rotate_iam_keys/rotate_iam_key_v1.py b/boto3/rotate_iam_keys/rotate_iam_key_v1.py new file mode 100644 index 0000000..e620d86 --- /dev/null +++ b/boto3/rotate_iam_keys/rotate_iam_key_v1.py @@ -0,0 +1,24 @@ +import boto3 +from datetime import datetime, timezone + + +client = boto3.client("iam") +sns = boto3.resource("sns") +paginator = client.get_paginator('list_users') +current_date=datetime.now(timezone.utc) +max_key_age=5 + +for response in paginator.paginate(): + for user in response['Users']: + username = user['UserName'] + + listkey = client.list_access_keys( + UserName=username) + for accesskey in listkey['AccessKeyMetadata']: + accesskey_id = accesskey['AccessKeyId'] + key_creation_date = accesskey['CreateDate'] + age = (current_date - key_creation_date).days + + if age > max_key_age: + print("Deactivating Key for the following users: " + username) + client.update_access_key(UserName=username, AccessKeyId=accesskey_id, Status='Inactive') diff --git a/boto3/rotate_iam_keys/rotate_iam_key_v2.py b/boto3/rotate_iam_keys/rotate_iam_key_v2.py new file mode 100644 index 0000000..5f51d37 --- /dev/null +++ b/boto3/rotate_iam_keys/rotate_iam_key_v2.py @@ -0,0 +1,27 @@ +import boto3 +from datetime import datetime, timezone + + +client = boto3.client("iam") +paginator = client.get_paginator('list_users') + +max_key_age=5 + +def rotate_key(key_creation_date): + current_date = datetime.now(timezone.utc) + age = (current_date - key_creation_date).days + return age + +for response in paginator.paginate(): + for user in response['Users']: + username = user['UserName'] + + listkey = client.list_access_keys( + UserName=username) + for accesskey in listkey['AccessKeyMetadata']: + accesskey_id = accesskey['AccessKeyId'] + key_creation_date = accesskey['CreateDate'] + age = rotate_key(key_creation_date) + if age > max_key_age: + print("Deactivating Key for the following users: " + username) + client.update_access_key(UserName=username, AccessKeyId=accesskey_id, Status='Inactive') diff --git a/boto3/rotate_iam_keys/rotate_iam_key_v3.py b/boto3/rotate_iam_keys/rotate_iam_key_v3.py new file mode 100644 index 0000000..3244e16 --- /dev/null +++ b/boto3/rotate_iam_keys/rotate_iam_key_v3.py @@ -0,0 +1,41 @@ +import boto3 +from datetime import datetime, timezone + +client = boto3.client("iam") +s3 = boto3.client("s3") +paginator = client.get_paginator('list_users') + +max_key_age = 5 +s3_bucket = "my-bucket-name" +s3_key_prefix = "new-keys/" + +def rotate_key(key_creation_date): + current_date = datetime.now(timezone.utc) + age = (current_date - key_creation_date).days + return age + +for response in paginator.paginate(): + for user in response['Users']: + username = user['UserName'] + + # Create a new access key for the user + response = client.create_access_key(UserName=username) + access_key_id = response['AccessKey']['AccessKeyId'] + secret_access_key = response['AccessKey']['SecretAccessKey'] + + # Upload the new access key to an S3 bucket(Please do it at your own risk) + s3_key = f"{s3_key_prefix}{access_key_id}.txt" + s3.put_object( + Bucket=s3_bucket, + Key=s3_key, + Body=f"Access Key ID: {access_key_id}\nSecret Access Key: {secret_access_key}" + ) + + listkey = client.list_access_keys(UserName=username) + for accesskey in listkey['AccessKeyMetadata']: + accesskey_id = accesskey['AccessKeyId'] + key_creation_date = accesskey['CreateDate'] + age = rotate_key(key_creation_date) + if age > max_key_age: + print(f"Deactivating key for the following user: {username}") + client.update_access_key(UserName=username, AccessKeyId=accesskey_id, Status='Inactive') diff --git a/boto3/rotate_iam_keys/rotate_iam_keys_v4.py b/boto3/rotate_iam_keys/rotate_iam_keys_v4.py new file mode 100644 index 0000000..808d3b7 --- /dev/null +++ b/boto3/rotate_iam_keys/rotate_iam_keys_v4.py @@ -0,0 +1,30 @@ +import boto3 +from datetime import datetime, timezone + +client = boto3.client("iam") +paginator = client.get_paginator('list_users') + +max_key_age = 5 +excluded_users = ["user1", "user2"] # List of usernames to exclude + +def rotate_key(key_creation_date): + current_date = datetime.now(timezone.utc) + age = (current_date - key_creation_date).days + return age + +for response in paginator.paginate(): + for user in response['Users']: + username = user['UserName'] + + if username in excluded_users: + # Skip processing excluded users + continue + + listkey = client.list_access_keys(UserName=username) + for accesskey in listkey['AccessKeyMetadata']: + accesskey_id = accesskey['AccessKeyId'] + key_creation_date = accesskey['CreateDate'] + age = rotate_key(key_creation_date) + if age > max_key_age: + print(f"Deactivating key for the following user: {username}") + client.update_access_key(UserName=username, AccessKeyId=accesskey_id, Status='Inactive') diff --git a/boto3/s3_object_private/s3_object_private.py b/boto3/s3_object_private/s3_object_private.py new file mode 100644 index 0000000..8045bee --- /dev/null +++ b/boto3/s3_object_private/s3_object_private.py @@ -0,0 +1,17 @@ +import boto3 +s3 = boto3.client("s3") + +for bucket in s3.list_buckets()['Buckets']: + bucket_name = bucket['Name'] + + all_objects = s3.list_objects(Bucket=bucket_name) + for obj in all_objects['Contents']: + bucket_key = obj['Key'] + + response = s3.get_object_acl(Bucket=bucket_name,Key=bucket_key) + + if len(response['Grants']) > 1: + + s3.put_object_acl(Bucket=bucket_name,Key=bucket_key,ACL="private") + + print(f"The Bucket {bucket_name} with key {bucket_key} is now marked as private") diff --git a/boto3/snapshot_cleanup/snapshot_cleanup.py b/boto3/snapshot_cleanup/snapshot_cleanup.py new file mode 100644 index 0000000..80dd57e --- /dev/null +++ b/boto3/snapshot_cleanup/snapshot_cleanup.py @@ -0,0 +1,20 @@ +import boto3 +from datetime import datetime, timedelta, timezone + +ec2 = boto3.resource('ec2') + +current_date = datetime.now(tz=timezone.utc) +diff_date = current_date - timedelta(days=10) + + +snapshots = ec2.snapshots.filter(OwnerIds=['self']) +for snapshot in snapshots: + snapshot_start_time = snapshot.start_time + if diff_date > snapshot_start_time: + try: + snapshot.delete() + print("Deleting Snapshot id: ", snapshot.snapshot_id) + + except Exception as e: + print("Current Snapshot is in use: ", snapshot.snapshot_id) + continue diff --git a/coding_interview/anagram/anagram1.py b/coding_interview/anagram/anagram1.py new file mode 100644 index 0000000..e641e30 --- /dev/null +++ b/coding_interview/anagram/anagram1.py @@ -0,0 +1,6 @@ +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + s = s.replace(" ","").lower() + t = t.replace(" ","").lower() + + return sorted(s) == sorted(t) diff --git a/coding_interview/anagram/anagram2.py b/coding_interview/anagram/anagram2.py new file mode 100644 index 0000000..788dcbe --- /dev/null +++ b/coding_interview/anagram/anagram2.py @@ -0,0 +1,27 @@ +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + s = s.replace(" ","").lower() + t = t.replace(" ","").lower() + + if len(s) != len(t): + return False + + count = {} + + for val1 in s: + if val1 in count: + count[val1] +=1 + else: + count[val1] =1 + + for val2 in t: + if val2 in count: + count[val2] -=1 + else: + count[val2] =1 + + for k in count: + if count[k] != 0: + return False + + return True diff --git a/coding_interview/array_pair_sum/array_pair_sum.py b/coding_interview/array_pair_sum/array_pair_sum.py new file mode 100644 index 0000000..5f7fe60 --- /dev/null +++ b/coding_interview/array_pair_sum/array_pair_sum.py @@ -0,0 +1,16 @@ +def array_pair_sum(arr,k): + if len(arr) < 2: + return + + seen = set() + output = set() + + for val in arr: + target = k - val + + if target not in seen: + seen.add(val) + else: + output.add(((min(target,val)),max(target,val))) + + return len(output) diff --git a/coding_interview/array_pair_sum_index/array_pair_sum_index1.py b/coding_interview/array_pair_sum_index/array_pair_sum_index1.py new file mode 100644 index 0000000..98cfa07 --- /dev/null +++ b/coding_interview/array_pair_sum_index/array_pair_sum_index1.py @@ -0,0 +1,7 @@ +#Using Brute Force Approach + +def twosum(nums,target): + for i in range(len(nums)): + for j in range(i+1, len(nums)): + if nums[j] == target - nums[i]: + return [i,j] diff --git a/coding_interview/array_pair_sum_index/array_pair_sum_index2.py b/coding_interview/array_pair_sum_index/array_pair_sum_index2.py new file mode 100644 index 0000000..ade0de8 --- /dev/null +++ b/coding_interview/array_pair_sum_index/array_pair_sum_index2.py @@ -0,0 +1,9 @@ +def twoSum(nums, target): + if len(nums) < 2: + return + hash = {} + for i , n in enumerate(nums): + if n in hash: + return [hash[n],i] + hash[target -n] = i + return [] diff --git a/coding_interview/array_pair_sum_index/array_pair_sum_index3.py b/coding_interview/array_pair_sum_index/array_pair_sum_index3.py new file mode 100644 index 0000000..433a884 --- /dev/null +++ b/coding_interview/array_pair_sum_index/array_pair_sum_index3.py @@ -0,0 +1,16 @@ +def twosum(arr,target): + if len(arr) < 2: + return False + + dict = {} + + for i in range(len(arr)): + diff = target - arr[i] + + if arr[i] in dict: + return dict[arr[i]],i + else: + dict[diff] = i + + +print(twosum([1,3,2,2],4)) diff --git a/coding_interview/finding_duplicate/finding_duplicate.py b/coding_interview/finding_duplicate/finding_duplicate.py new file mode 100644 index 0000000..5f21d5e --- /dev/null +++ b/coding_interview/finding_duplicate/finding_duplicate.py @@ -0,0 +1,12 @@ +def duplicate(x): + dict = {} + for val in x: + if val in dict: + return True + else: + dict[val] = 1 + return False + + + +print(duplicate([1,2,3,1])) diff --git a/coding_interview/largest_continious_sum/largest_continous_sum1.py b/coding_interview/largest_continious_sum/largest_continous_sum1.py new file mode 100644 index 0000000..0c4a11a --- /dev/null +++ b/coding_interview/largest_continious_sum/largest_continous_sum1.py @@ -0,0 +1,9 @@ +def largest_sum(arr): + if len(arr) == 0: + return False + max_sum = cur_sum = arr[0] + + for val in arr[1:]: + cur_sum = max(cur_sum+val, val) + max_sum = max(cur_sum,max_sum) + return max_sum diff --git a/coding_interview/length_of_longest_substring/length_of_longest_substring.py b/coding_interview/length_of_longest_substring/length_of_longest_substring.py new file mode 100644 index 0000000..22befe8 --- /dev/null +++ b/coding_interview/length_of_longest_substring/length_of_longest_substring.py @@ -0,0 +1,14 @@ +def lengthOfLongestSubstring(s): + charSet = set() + l = 0 + res = 0 + + for r in range(len(s)): + while s[r] in charSet: + charSet.remove(s[l]) + l += 1 + charSet.add(s[r]) + res = max(res, r - l + 1) + return res + +print(lengthOfLongestSubstring("abcabcbb")) diff --git a/coding_interview/palindrome_check/palindrome_check.py b/coding_interview/palindrome_check/palindrome_check.py new file mode 100644 index 0000000..6306ccb --- /dev/null +++ b/coding_interview/palindrome_check/palindrome_check.py @@ -0,0 +1,16 @@ +# Leet Code Problem: https://leetcode.com/problems/palindrome-number/submissions/ +# Negative number can't be palindrome -123 reverse is 321- +# Some other way to solve the problem is to convert integer to string and then reverse it +# Time complexity O(n) and Space Complexity 0(1) + +def ispalindrome(x): + if x < 0: + return True + b = 0 + c = x + while c: + b = b * 10 + c % 10 + c = int(c/10) + return x == b + +print(ispalindrome(121)) diff --git a/coding_interview/palindrome_check/palindrome_check1.py b/coding_interview/palindrome_check/palindrome_check1.py new file mode 100644 index 0000000..1e82de8 --- /dev/null +++ b/coding_interview/palindrome_check/palindrome_check1.py @@ -0,0 +1,19 @@ +def isPalindrome(s): + res = "" + + for val in s: + if val.isalnum(): + res = res + val.lower() + + length = len(res) + l = 0 + r = length -1 + + while l < r: + if res[l] != res[r]: + return False + l +=1 + r -=1 + return True + +print(isPalindrome("A man, a plan, a canal: Panama")) diff --git a/coding_interview/reverse_a_sentence/reverse_a_sentence1.py b/coding_interview/reverse_a_sentence/reverse_a_sentence1.py new file mode 100644 index 0000000..939e454 --- /dev/null +++ b/coding_interview/reverse_a_sentence/reverse_a_sentence1.py @@ -0,0 +1,2 @@ +def reverse(s): + return " ".join(reversed(s.split())) diff --git a/coding_interview/reverse_a_string/reverse_a_string.py b/coding_interview/reverse_a_string/reverse_a_string.py new file mode 100644 index 0000000..35c5804 --- /dev/null +++ b/coding_interview/reverse_a_string/reverse_a_string.py @@ -0,0 +1,11 @@ +def reverseString(s): + length = len(s) + l = 0 + r = length -1 + while l < r: + s[l], s[r] = s[r], s[l] + l +=1 + r -=1 + + +print(reverseString(["h","e","l","l","o"])) diff --git a/coding_interview/reverse_integer/reverse_integer.py b/coding_interview/reverse_integer/reverse_integer.py new file mode 100644 index 0000000..aae2316 --- /dev/null +++ b/coding_interview/reverse_integer/reverse_integer.py @@ -0,0 +1,29 @@ +# Leet Code Problem: https://leetcode.com/problems/reverse-integer/ +# Modulus and division of negative number shows some unexpected result int(divider/number) and number % -divisor +# Time Complexity 0(n) and Space Complexity 0(1) + +def divide(number, divider): + return int(number/divider) + +def mod(number,divisor): + if number < 0: + return number % -divisor + return number % divisor + +MAX_INT = 2 ** 31 -1 +MIN_INT = -2 ** 31 + +def reverse(x): + res = 0 + while x: + pop = mod(x,10) + x = divide(x,10) + if res > divide(MAX_INT, 10) or (res == divide(MAX_INT,10) and pop > 7): + return 0 + if res < divide(MIN_INT, 10) or (res == divide(MIN_INT,10) and pop < -8): + return 0 + res = res * 10 + pop + return res + + +print(reverse(123)) diff --git a/coding_interview/roman_to_integer/roman_to_integer.py b/coding_interview/roman_to_integer/roman_to_integer.py new file mode 100644 index 0000000..35c8e8b --- /dev/null +++ b/coding_interview/roman_to_integer/roman_to_integer.py @@ -0,0 +1,26 @@ +def romanToInt(s): + lookup = { + "I":1, + "V":5, + "X":10, + "L":50, + "C":100, + "D":500, + "M":1000 + } + + curr = prev = total = 0 + for i in range(len(s)): + curr = lookup[s[i]] + + if curr > prev: + total = total + curr - 2 * prev + else: + total = total + curr + + prev = curr + return total + + + +print(romanToInt("IV")) diff --git a/coding_interview/three_sum/three_sum.py b/coding_interview/three_sum/three_sum.py new file mode 100644 index 0000000..64a8d23 --- /dev/null +++ b/coding_interview/three_sum/three_sum.py @@ -0,0 +1,36 @@ +def threesum(arr, target): + res = [] + arr.sort() + + length = len(arr) + + for i in range(length -2): + if i > 0 and arr[i] == arr[i-1]: + continue + l = i +1 + r = length -1 + + while l < r: + total = arr[i] + arr[l] + arr[r] + + if total < target: + l += 1 + elif total > target: + r -=1 + else: + res.append([arr[i],arr[l],arr[r]]) + while l < r and arr[l] == arr[l+1]: + l += 1 + while l < r and arr[r] == arr[r-1]: + r -= 1 + + l +=1 + r -=1 + return res + +print(threesum([-1,0,1,2,-1,-4],0)) + + + + + diff --git a/coding_interview/unique_character_in_string/unique_char1.py b/coding_interview/unique_character_in_string/unique_char1.py new file mode 100644 index 0000000..dc7a374 --- /dev/null +++ b/coding_interview/unique_character_in_string/unique_char1.py @@ -0,0 +1,3 @@ +def unique_char(s): + if len(set(s)) == len(s): + return True diff --git a/coding_interview/unique_character_in_string/unique_char2.py b/coding_interview/unique_character_in_string/unique_char2.py new file mode 100644 index 0000000..d707442 --- /dev/null +++ b/coding_interview/unique_character_in_string/unique_char2.py @@ -0,0 +1,10 @@ +def unique_char(s): + chars = set() + + for val in s: + if val in chars: + return False + else: + chars.add(val) + + return True diff --git a/coding_interview/valid_parenthesis/valid_parenthesis.py b/coding_interview/valid_parenthesis/valid_parenthesis.py new file mode 100644 index 0000000..43a6515 --- /dev/null +++ b/coding_interview/valid_parenthesis/valid_parenthesis.py @@ -0,0 +1,15 @@ +def isValid(s): + stack = [] + closeToOpen = { ")": "(","]" : "[", "}" : "{" } + + for c in s: + if c in closeToOpen: + if stack and stack[-1] == closeToOpen[c]: + stack.pop() + else: + return False + else: + stack.append(c) + return True if not stack else False + +print(isValid("()[]{}")) diff --git a/docker_jenkins/Dockerfile b/docker_jenkins/Dockerfile new file mode 100644 index 0000000..df2d700 --- /dev/null +++ b/docker_jenkins/Dockerfile @@ -0,0 +1,2 @@ +FROM node:14-alpine +RUN apk add -U subversion diff --git a/docker_jenkins/Jenkinsfile b/docker_jenkins/Jenkinsfile new file mode 100644 index 0000000..d543197 --- /dev/null +++ b/docker_jenkins/Jenkinsfile @@ -0,0 +1,11 @@ +pipeline { + agent { dockerfile true } + stages { + stage('Test') { + steps { + sh 'node --version' + sh 'svn --version' + } + } + } +} diff --git a/ebs_volume_conversion/README.md b/ebs_volume_conversion/README.md new file mode 100644 index 0000000..d487bde --- /dev/null +++ b/ebs_volume_conversion/README.md @@ -0,0 +1,35 @@ +# Python script to convert EBS Volume + +Python script to convert EBS volume from gp2 to gp3 or from io1 to io2 and read input from csv file with a format volume_id,volume_type + +## Usage + +```python3 ebs_volume_conversion.py -h +usage: ebs_volume_conversion.py [-h] [-f FILE] volume_id volume_type + +positional arguments: + volume_id The EBS volume id of the Volume to be convert + volume_type The new EBS volume type to be converted gp3 or io2 + +optional arguments: + -h, --help show this help message and exit + -f FILE, --file FILE A csv file containing ebs volume id and volume type to convert +``` + +# Example + +1. To convert an ebs volume from gp2 to gp3 + +``` +python3 ebs_volume_conversion.py -volume_id -volume_type gp3 +``` + +2. To convert an ebs volume from io1 to io2 +``` +python3 ebs_volume_conversion.py -volume_id -volume_type io2 +``` + +3. You can pass a csv file containing ebs volume id and volume type to convert +``` +python3 ebs_volume_conversion.py -f ebs_volume.csv +``` diff --git a/ebs_volume_conversion/ebs_volume_conversion.py b/ebs_volume_conversion/ebs_volume_conversion.py new file mode 100644 index 0000000..c9ca367 --- /dev/null +++ b/ebs_volume_conversion/ebs_volume_conversion.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# Python script to convert EBS volume from gp2 to gp3 or from io1 to io2 and read input from csv file with a format volume_id,volume_type + +import boto3 +import argparse +import csv +import sys + +def convert_ebs_vol(volume_id,volume_type): + # Create an EC2 client + ec2 = boto3.client('ec2') + # Ask user if he want to take the snapshot before volume conversion + snapshot = input(f'Do you want to take the snapshot of the following volume {volume_id} before conversion? (y/n)') + # Take the snapshot if user confirms + if snapshot.lower() == 'y': + try: + snapshot = ec2.create_snapshot(VolumeId=volume_id,Description="Snapshot before converting the EBS volume") + # Wait for the snapshot to be completed + waiter = ec2.get_waiter('snapshot_completed') + waiter.wait(SnapshotIds=[snapshot['SnapshotId']]) + print(f'Sucessfully created the snapshot {snapshot["SnapshotId"]} of volume {volume_id}') + except Exception as e: + print(f'An error occurred while creating the snapshot for volume {volume_id}: {e} ') + exit(1) + try: + # Modify the EBS Volume to the new volume type + ec2.modify_volume(VolumeId=volume_id, VolumeType=volume_type) + print(f'Started converting EBS volume {volume_id} to {volume_type}') + # Wait until the EBS volume is available + ec2.get_waiter('volume_available').wait(VolumeIds=[volume_id]) + print(f'Sucessfully converted EBS volume {volume_id} to {volume_type}') + except Exception as e: + print(f'An error occurred while converting the EBS volume {volume_id}: {e} ') + exit(1) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-volume_id", help="The EBS volume id of the Volume to be convert") + parser.add_argument("-volume_type", help="The new EBS volume type to be converted gp3 or io2") + parser.add_argument("-f","--file", help="A csv file containing ebs volume id and volume type to convert") + args = parser.parse_args() + if not any(vars(args).values()): + parser.print_help() + sys.exit() + + if args.file: + with open(args.file, 'r') as f: + reader = csv.reader(f) + for row in reader: + volume_id = row[0] + volume_type = row[1] + convert_ebs_vol(volume_id, volume_type) + else: + convert_ebs_vol(args.volume_id, args.volume_type) diff --git a/ec2_instance_conversion/README.md b/ec2_instance_conversion/README.md new file mode 100644 index 0000000..882e89c --- /dev/null +++ b/ec2_instance_conversion/README.md @@ -0,0 +1,35 @@ +# Python script to convert EC2 instance + +Python script to convert EC2 instance from one type to another and read input from csv file with a format instance_id,instance_type + + +## Usage + +```python3 ec2_instance_conversion.py +usage: ec2_instance_conversion.py [-h] [-instance_id INSTANCE_ID] + [-new_instance_type NEW_INSTANCE_TYPE] [-f FILE] + +Convert an EC2 instance from one type to another + +optional arguments: + -h, --help show this help message and exit + -instance_id INSTANCE_ID + The ID of the EC2 instance to convert + -new_instance_type NEW_INSTANCE_TYPE + The new instance type for the EC2 instance + -f FILE, --file FILE A CSV file containing a list of instances and new instance types +``` + +# Example + +1. To convert an EC2 instance to t2.medium + +``` +python3 ec2_instance_conversion.py -instance_id -new_instance_type t2.medium +``` + + +3. You can pass a csv file containing instance id and instance type to convert +``` +python3 ec2_instance_conversion.py -f ec2_conversion.csv +``` diff --git a/ec2_instance_conversion/ec2_instance_conversion.py b/ec2_instance_conversion/ec2_instance_conversion.py new file mode 100644 index 0000000..c9134f8 --- /dev/null +++ b/ec2_instance_conversion/ec2_instance_conversion.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# Python script to convert EC2 instance from one type to another and read input from csv file with a format instance_id,instance_type + +import argparse +import boto3 +import sys +import csv + +def convert_instance(instance_id, new_instance_type, csv_file=None): + # Create an EC2 client + ec2 = boto3.client('ec2') + + # Check if the instance is in a stopped state + response = ec2.describe_instances(InstanceIds=[instance_id]) + instance_state = response['Reservations'][0]['Instances'][0]['State']['Name'] + if instance_state == 'stopped': + snapshot_response = input("The instance is in a stopped state. Please don't forget to take the ebs snapshot of the instance volume before the conversion y/n") + try: + # Modify the instance + ec2.modify_instance_attribute(InstanceId=instance_id, Attribute='instanceType', Value=new_instance_type) + print("Successfully converted instance", instance_id, "to", new_instance_type) + except Exception as e: + print("Error converting instance:", e) + +if __name__ == '__main__': + # Set up the argument parser + parser = argparse.ArgumentParser(description='Convert an EC2 instance from one type to another') + parser.add_argument('-instance_id', help='The ID of the EC2 instance to convert') + parser.add_argument('-new_instance_type', help='The new instance type for the EC2 instance') + parser.add_argument("-f","--file", help='A CSV file containing a list of instances and new instance types') + args = parser.parse_args() + if not any(vars(args).values()): + parser.print_help() + sys.exit() + if args.file: + with open(args.file, 'r') as f: + reader = csv.reader(f) + for row in reader: + instance_id = row[0] + new_instance_type = row[1] + convert_instance(instance_id, new_instance_type) + else: + convert_instance(args.instance_id, args.new_instance_type) diff --git a/eks-codepipeline/Dockerfile b/eks-codepipeline/Dockerfile new file mode 100644 index 0000000..154e78b --- /dev/null +++ b/eks-codepipeline/Dockerfile @@ -0,0 +1,2 @@ +FROM public.ecr.aws/nginx/nginx:latest +COPY app /usr/share/nginx/html/app \ No newline at end of file diff --git a/eks-codepipeline/app/index.html b/eks-codepipeline/app/index.html new file mode 100644 index 0000000..b2c970f --- /dev/null +++ b/eks-codepipeline/app/index.html @@ -0,0 +1,6 @@ + + +

Welcome to Pipeline for EKS using CodeCommit, CodeBuild and CodePipeline

+

This is demo pipeline for EKS - v1

+ + \ No newline at end of file diff --git a/eks-codepipeline/buildspec.yml b/eks-codepipeline/buildspec.yml new file mode 100644 index 0000000..8105778 --- /dev/null +++ b/eks-codepipeline/buildspec.yml @@ -0,0 +1,53 @@ +version: 0.2 +phases: + install: + commands: + - echo "Install Phase - if you need additional package, add it in this stage" + pre_build: + commands: + # This Docker Image tag will have date, time and Codecommit version + - TAG="$(date +%Y-%m-%d.%H.%M.%S).$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)" + # Updating Docker Image tag in your Kubernetes Deployment Manifest + - echo "Update Image tag in kubernetes manifest" + - sed -i 's@CONTAINER_IMAGE@'"$REPOSITORY_URL:$TAG"'@' manifests/deployment.yaml + # Check AWS CLI Version + - echo "Checking AWS CLI Version..." + - aws --version + # Login to ECR Registry + - echo "Login in to Amazon ECR Registry" + - $(aws ecr get-login --no-include-email) + # Update Kube config Home Directory + - export KUBECONFIG=$HOME/.kube/config + build: + commands: + # Building Docker Image + - echo "Docker build started on `date`" + - echo "Building the Docker image..." + - docker build --tag $REPOSITORY_URL:$TAG . + post_build: + commands: + # Push Docker Image to ECR Repository + - echo "Docker build completed on `date`" + - echo "Pushing the Docker image to ECR Repository" + - docker push $REPOSITORY_URL:$TAG + - echo "Docker Push to ECR Repository Completed - $REPOSITORY_URL:$TAG" + # Get AWS Credential using STS Assume Role for kubectl + - echo "Setting Environment Variables related to AWS CLI for Kube Config Setup" + - CREDENTIALS=$(aws sts assume-role --role-arn $EKS_ROLE_ARN --role-session-name eks-codebuild --duration-seconds 900) + - export AWS_ACCESS_KEY_ID="$(echo ${CREDENTIALS} | jq -r '.Credentials.AccessKeyId')" + - export AWS_SECRET_ACCESS_KEY="$(echo ${CREDENTIALS} | jq -r '.Credentials.SecretAccessKey')" + - export AWS_SESSION_TOKEN="$(echo ${CREDENTIALS} | jq -r '.Credentials.SessionToken')" + - export AWS_EXPIRATION=$(echo ${CREDENTIALS} | jq -r '.Credentials.Expiration') + # Updating kubectl with your EKS Cluster + - echo "Update Kube Config configuration" + - aws eks update-kubeconfig --name $EKS_CLUSTERNAME + # Show time, applying manifests changes using kubectl + - echo "Apply changes to kube manifests" + - kubectl apply -f manifests/ + - echo "All done!!!! Kubernetes changes applied" + # Create Artifacts which we can use if we want to continue our pipeline for other stages + - printf '[{"name":"deployment.yaml","imageUri":"%s"}]' $REPOSITORY_URL:$TAG > build.json +artifacts: + files: + - build.json + - manifests/* \ No newline at end of file diff --git a/eks-codepipeline/manifests/deployment.yaml b/eks-codepipeline/manifests/deployment.yaml new file mode 100644 index 0000000..3a0ab03 --- /dev/null +++ b/eks-codepipeline/manifests/deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-eks-pipeline-deployment + labels: + app: my-eks-pipeline-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: my-eks-pipeline-deployment + template: + metadata: + labels: + app: my-eks-pipeline-deployment + spec: + containers: + - name: my-eks-pipeline-deployment + image: CONTAINER_IMAGE + ports: + - containerPort: 80 \ No newline at end of file diff --git a/enabling_vpc_flow_log/enabling_vpc_flow_log.py b/enabling_vpc_flow_log/enabling_vpc_flow_log.py new file mode 100644 index 0000000..4961a16 --- /dev/null +++ b/enabling_vpc_flow_log/enabling_vpc_flow_log.py @@ -0,0 +1,33 @@ +import boto3 +from botocore.exceptions import ClientError + + +client = boto3.client("ec2") +client_log = boto3.client('logs') + + +for vpcid in client.describe_vpcs()['Vpcs']: + vpc_id = vpcid['VpcId'] + print(vpc_id) + + log_group = vpc_id + "-flowlog" + + try: + response = client_log.create_log_group( + logGroupName=log_group) + except ClientError: + print("Log group already exist for the following vpc: ", vpc_id) + + flow_log_filter={"Name":"resource-id","Values":[vpc_id]} + response = client.describe_flow_logs(Filters=[flow_log_filter]) + if len(response['FlowLogs']) > 0: + print("VPC Flowlog is already enabled for this VPC: ", vpc_id) + else: + print("Enabling Flow logs for the following VPC: ") + response = client.create_flow_logs( + ResourceIds=[vpc_id], + ResourceType='VPC', + TrafficType='ALL', + LogGroupName=log_group, + DeliverLogsPermissionArn="" + ) diff --git a/environment_setup/environment_setup.sh b/environment_setup/environment_setup.sh new file mode 100644 index 0000000..a4651b0 --- /dev/null +++ b/environment_setup/environment_setup.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# This shell script that checks if the required python modules (pip3, boto3, and awscli) +# the terraform package are installed, and installs them if they are missing. +# This script should work on both CentOS and macOS +# Check the terraform release page to use the latest terraform package https://releases.hashicorp.com/terraform/ +# Author: Prashant Lakhera(laprashant@gmail.com) + +# Check if pip3 is installed +if ! type "pip3" &> /dev/null +then + echo "pip3 is not installed. Installing now ..." + # Install pip3 + # Checking for Mac + if [ "$(uname)" == "Darwin" ] + then + brew install python3 + # Checking for Centos + elif [ -f /etc/centos-release ] + then + sudo yum -y update + sudo yum -y install python3-pip -y + fi +fi + +# Check if boto3 is installed +if python3 -c "import boto3" &> /dev/null; then + echo "Boto3 is already installed" +else + echo "Boto3 is not installed. Installing now...." + pip3 install boto3 --user +fi + +# Check if awscli is installed +if ! type "aws" > /dev/null +then + echo "awscli is not installed. Installing now..." + pip3 install awscli --user +else + echo "awscli is already installed" +fi + +# Check if terraform is installed +if ! type "terraform" > /dev/null +then + echo "terraform is not installed installing now..." + # Install terraform + #Checking for Mac + if [ "$(uname)" == "Darwin" ] + then + brew install terraform + # Checking for Centos + elif [ -f /etc/centos-release ] + then + sudo yum install -y unzip + sudo wget https://releases.hashicorp.com/terraform/1.3.6/terraform_1.3.6_linux_amd64.zip + sudo unzip terraform_1.3.6_linux_amd64.zip + sudo mv terraform /usr/local/bin/ + sudo chmod +x /usr/local/bin/terraform + sudo rm terraform_1.3.6_linux_amd64.zip + fi +else + echo "Terraform is already installed" + +fi \ No newline at end of file diff --git a/find_files_greater_than_X_days_old/find_files_greater_then_X_days.py b/find_files_greater_than_X_days_old/find_files_greater_then_X_days.py new file mode 100644 index 0000000..5723d67 --- /dev/null +++ b/find_files_greater_than_X_days_old/find_files_greater_then_X_days.py @@ -0,0 +1,15 @@ +import os +import datetime + +currentdate=datetime.datetime.now() +max_age=15 + +for dirpath, dirname, filename in os.walk("/etc/openldap"): + for file in filename: + comp_path= os.path.join(dirpath,file) + file_stat=os.stat(comp_path) + file_ctime = file_stat.st_ctime + file_creation_in_days= datetime.datetime.fromtimestamp(file_ctime) + diff_in_days=(currentdate - file_creation_in_days).days + if diff_in_days > max_age: + print(comp_path, diff_in_days) diff --git a/get_pass_module/get_pass_module.py b/get_pass_module/get_pass_module.py new file mode 100644 index 0000000..02e2183 --- /dev/null +++ b/get_pass_module/get_pass_module.py @@ -0,0 +1,2 @@ +import getpass +my_pass=getpass.getpass(prompt="Enter your password: ") diff --git a/github_automation/create_del_list_arg.py b/github_automation/create_del_list_arg.py new file mode 100644 index 0000000..0eabe72 --- /dev/null +++ b/github_automation/create_del_list_arg.py @@ -0,0 +1,47 @@ +import requests +from pprint import pprint +import os +import json +import argparse + + +VALID_TYPES = ['all', 'owner', 'public', 'private', 'member'] + +my_parser = argparse.ArgumentParser() +my_parser.add_argument("--reponame","--r", dest="reponame", + help='Please enter the repository name') +my_parser.add_argument("--deleterepo","--d",dest="deleterepo", + help='To delete a repository') +my_parser.add_argument("--listrepo","--l",dest="listrepo", + help='To list a repository owned by "all, owner, public, private, member" default value is all', default='all', choices = VALID_TYPES) + + +args = my_parser.parse_args() + +token = os.environ.get("GITHUB_TOKEN") + +# https://advanced-python.readthedocs.io/en/latest/rest/list_repos.html + +reponame = args.reponame +deleterepo = args.deleterepo +listrepo = args.listrepo + + +GITHUB_API_URL = "https://api.github.com/" +headers = {"Authorization": "token {}".format(token)} +data = {"name": "{}".format(reponame)} + +if reponame: + r = requests.post(GITHUB_API_URL +"user/repos" + "", data=json.dumps(data), headers=headers) + +if deleterepo: + username = input("Please enter your GitHub username: ") + r = requests.delete("https://api.github.com/repos/{}/{}".format(username,deleterepo), headers=headers) + print(r) + +if listrepo: + username = input("Please enter your GitHub username: ") + output = requests.get("https://api.github.com/users/{}/repos".format(username)) + output = json.loads(output.text) + for repo in output: + pprint(repo["name"]) diff --git a/github_automation/create_repo.py b/github_automation/create_repo.py new file mode 100644 index 0000000..2fa0d06 --- /dev/null +++ b/github_automation/create_repo.py @@ -0,0 +1,13 @@ +import requests +import os +import json + +token = os.environ.get("GITHUB_TOKEN") +reponame = input("Please enter the repo name you want to create : ") + +GITHUB_API_URL = "https://api.github.com/" +headers = {"Authorization": "token {}".format(token)} +data = {"name": "{}".format(reponame)} + +r = requests.post(GITHUB_API_URL +"user/repos" + "", data=json.dumps(data), headers=headers) +print(r) diff --git a/github_automation/delete_repo.py b/github_automation/delete_repo.py new file mode 100644 index 0000000..7d8567a --- /dev/null +++ b/github_automation/delete_repo.py @@ -0,0 +1,14 @@ +import requests +import os +import json + +token = os.environ.get("GITHUB_TOKEN") +reponame = input("Please enter the repo name you want to delete : ") + +GITHUB_API_URL = "https://api.github.com/" +headers = {"Authorization": "token {}".format(token)} +data = {"name": "{}".format(reponame)} + +username = input("Please enter your GitHub username: ") +r = requests.delete("https://api.github.com/repos/{}/{}".format(username, reponame), headers=headers) +print(r) diff --git a/github_automation/downloading_all_repos.py b/github_automation/downloading_all_repos.py new file mode 100644 index 0000000..2e55195 --- /dev/null +++ b/github_automation/downloading_all_repos.py @@ -0,0 +1,25 @@ +import requests +import os + +# Replace with your GitHub username and personal access token +username = "your-username" +access_token = "your-access-token" + +# Set the base URL for the GitHub API +base_url = "https://api.github.com" + +# Create a session with the access token to authenticate requests +session = requests.Session() +session.auth = (username, access_token) + +# Get the list of repositories for the authenticated user +repositories_url = f"{base_url}/user/repos" +response = session.get(repositories_url) +repositories = response.json() + +# Loop over the repositories and clone them to a local directory +for repository in repositories: + name = repository["name"] + clone_url = repository["clone_url"] + print(f"Cloning {name} from {clone_url}") + os.system(f"git clone {clone_url}") diff --git a/github_automation/list_repos.py b/github_automation/list_repos.py new file mode 100644 index 0000000..8196f17 --- /dev/null +++ b/github_automation/list_repos.py @@ -0,0 +1,12 @@ +import requests +import os +import json + +data = {"type": "all", "sort":"full_name", "direction": "asc"} + +username = input("Please enter your GitHub username: ") +output = requests.get("https://api.github.com/users/{}/repos".format(username), data=json.dumps(data)) +output = json.loads(output.text) + +for reponame in output: + print(reponame['name']) diff --git a/iam_policies/1-1-allow-access-to-EC2-S3.json b/iam_policies/1-1-allow-access-to-EC2-S3.json new file mode 100644 index 0000000..f224161 --- /dev/null +++ b/iam_policies/1-1-allow-access-to-EC2-S3.json @@ -0,0 +1,14 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Statement1", + "Effect": "Allow", + "Action": [ + "ec2:*", + "s3:*" + ], + "Resource": "*" + } + ] +} diff --git a/iam_policies/1-1-deny-access-to-EC2-S3.json b/iam_policies/1-1-deny-access-to-EC2-S3.json new file mode 100644 index 0000000..1dcef0d --- /dev/null +++ b/iam_policies/1-1-deny-access-to-EC2-S3.json @@ -0,0 +1,14 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Statement1", + "Effect": "Deny", + "Action": [ + "ec2:*", + "s3:*" + ], + "Resource": "*" + } + ] +} diff --git a/iam_policies/10-1-deny-root-access.json b/iam_policies/10-1-deny-root-access.json new file mode 100644 index 0000000..5bcae1e --- /dev/null +++ b/iam_policies/10-1-deny-root-access.json @@ -0,0 +1,16 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Deny", + "Action": "*", + "Resource": "*", + "Condition": { + "StringLike": { + "aws:PrincipalArn": "arn:aws:iam::*:root" + } + } + } + ] +} diff --git a/iam_policies/2-1-allow-access-to-approved-regions.json b/iam_policies/2-1-allow-access-to-approved-regions.json new file mode 100644 index 0000000..b5cf938 --- /dev/null +++ b/iam_policies/2-1-allow-access-to-approved-regions.json @@ -0,0 +1,22 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "DenyAllOutsideRequestedRegions", + "Effect": "Deny", + "NotAction": [ + "ec2:*", + "s3:*" + ], + "Resource": "*", + "Condition": { + "StringNotEquals": { + "aws:RequestedRegion": [ + "us-west-1", + "us-west-2" + ] + } + } + } + ] +} diff --git a/iam_policies/3-1-create-only-specific-type-instance.json b/iam_policies/3-1-create-only-specific-type-instance.json new file mode 100644 index 0000000..583cac3 --- /dev/null +++ b/iam_policies/3-1-create-only-specific-type-instance.json @@ -0,0 +1,15 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Deny", + "Action": "ec2:RunInstances", + "Resource": "arn:aws:ec2:*:*:instance/*", + "Condition": { + "ForAnyValue:StringNotLike": { + "ec2:InstanceType": "t2.micro" + } + } + } + ] diff --git a/iam_policies/4-1-allowed-access-to-specific-ec2-instance.json b/iam_policies/4-1-allowed-access-to-specific-ec2-instance.json new file mode 100644 index 0000000..c551396 --- /dev/null +++ b/iam_policies/4-1-allowed-access-to-specific-ec2-instance.json @@ -0,0 +1,13 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": "ec2:*", + "Resource": [ + "arn:aws:ec2:*::instance/" + ] + } + ] +} diff --git a/iam_policies/5-1-iam-admin-permission-without-escalating-it.json b/iam_policies/5-1-iam-admin-permission-without-escalating-it.json new file mode 100644 index 0000000..d7792b1 --- /dev/null +++ b/iam_policies/5-1-iam-admin-permission-without-escalating-it.json @@ -0,0 +1,89 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "FullAdminAccess", + "Effect": "Allow", + "Action": "*", + "Resource": "*" + }, + { + "Sid": "DenyAccessToSageMaker", + "Effect": "Deny", + "Action": [ + "sagemaker:*" + ], + "Resource": "*" + }, + { + "Sid": "DenyIAMPolicyChanges", + "Effect": "Deny", + "Action": [ + "iam:DeletePolicy", + "iam:DeletePolicyVersion", + "iam:CreatePolicyVersion", + "iam:SetDefaultPolicyVersion" + ], + "Resource": [ + "arn:aws:iam::REPLACE-AWS-USER:policy/DemoPermissionsBoundary" + ] + }, + { + "Sid": "DenyRemovalOfPermBoundary", + "Effect": "Deny", + "Action": [ + "iam:DeleteUserPermissionsBoundary", + "iam:DeleteRolePermissionsBoundary" + ], + "Resource": [ + "arn:aws:iam::REPLACE-AWS-USER:user/*", + "arn:aws:iam::REPLACE-AWS-USER:role/*" + ], + "Condition": { + "StringEquals": { + "iam:PermissionsBoundary": "arn:aws:iam::REPLACE-AWS-USER:policy/DemoPermissionsBoundary" + } + } + }, + { + "Sid": "DenyAccessIfRequiredPermBoundaryIsNotBeingAttached", + "Effect": "Deny", + "Action": [ + "iam:PutUserPermissionsBoundary", + "iam:PutRolePermissionsBoundary" + ], + "Resource": [ + "arn:aws:iam::REPLACE-AWS-USER:user/*", + "arn:aws:iam::REPLACE-AWS-USER:role/*" + ], + "Condition": { + "StringNotEquals": { + "iam:PermissionsBoundary": "arn:aws:iam::REPLACE-AWS-USER:policy/DemoPermissionsBoundary" + } + } + }, + { + "Sid": "DenyUserAndRoleCreationIfPermBoundaryNotAttached", + "Effect": "Deny", + "Action": [ + "iam:CreateUser", + "iam:CreateRole" + ], + "Resource": [ + "arn:aws:iam::REPLACE-AWS-USER:user/*", + "arn:aws:iam::REPLACE-AWS-USER:role/*" + ], + "Condition": { + "StringNotEquals": { + "iam:PermissionsBoundary": "arn:aws:iam::REPLACE-AWS-USER:policy/DemoPermissionsBoundary" + } + } + }, + { + "Sid": "DenyIAMActions", + "Effect": "Deny", + "Action": "iam:PassRole", + "Resource": "arn:aws:iam::REPLACE-AWS-USER:role/*" + } + ] +} diff --git a/iam_policies/6-1-restrict-s3-access-from-specific-ip.json b/iam_policies/6-1-restrict-s3-access-from-specific-ip.json new file mode 100644 index 0000000..a043ed5 --- /dev/null +++ b/iam_policies/6-1-restrict-s3-access-from-specific-ip.json @@ -0,0 +1,21 @@ +{ + "Version": "2012-10-17", + "Id": "SourceIPAccess", + "Statement": [ + { + "Sid": "SourceIPAccess", + "Effect": "Deny", + "Principal": "*", + "Action": "s3:*", + "Resource": [ + "arn:aws:s3:::Bucket-name", + "arn:aws:s3:::Bucket-name/*" + ], + "Condition": { + "NotIpAddress": { + "aws:SourceIp": "" + } + } + } + ] +} diff --git a/iam_policies/6-2-restrict-s3-access-from-specific-vpc-endpoint.json b/iam_policies/6-2-restrict-s3-access-from-specific-vpc-endpoint.json new file mode 100644 index 0000000..f408212 --- /dev/null +++ b/iam_policies/6-2-restrict-s3-access-from-specific-vpc-endpoint.json @@ -0,0 +1,23 @@ +{ + "Id": "VPCe", + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VPCe", + "Action": "s3:*", + "Effect": "Deny", + "Resource": [ + "arn:aws:s3:::example-bucket", + "arn:aws:s3:::example-bucket/*" + ], + "Condition": { + "StringNotEquals": { + "aws:SourceVpce": [ + "vpce-1111111" + ] + } + }, + "Principal": "*" + } + ] +} diff --git a/iam_policies/7-1-allow-user-access-to-home-folder.json b/iam_policies/7-1-allow-user-access-to-home-folder.json new file mode 100644 index 0000000..1388743 --- /dev/null +++ b/iam_policies/7-1-allow-user-access-to-home-folder.json @@ -0,0 +1,35 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:ListAllMyBuckets", + "s3:GetBucketLocation" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": "s3:ListBucket", + "Resource": "arn:aws:s3:::", + "Condition": { + "StringLike": { + "s3:prefix": [ + "", + "home/", + "home/${aws:username}/*" + ] + } + } + }, + { + "Effect": "Allow", + "Action": "s3:*", + "Resource": [ + "arn:aws:s3:::/home/${aws:username}", + "arn:aws:s3:::/home/${aws:username}/*" + ] + } + ] +} diff --git a/iam_policies/8-1-user-cannot-turnoff-disable-cloudtrail.json b/iam_policies/8-1-user-cannot-turnoff-disable-cloudtrail.json new file mode 100644 index 0000000..d5a8cec --- /dev/null +++ b/iam_policies/8-1-user-cannot-turnoff-disable-cloudtrail.json @@ -0,0 +1,11 @@ +{ + "Version": "2012-10-17", + "Statement": { + "Effect": "Deny", + "Action": [ + "cloudtrail:StopLogging", + "cloudtrail:DeleteTrail" + ], + "Resource": "*" + } +} diff --git a/iam_policies/9-1-deny-access-to-any-gateway-attachment.json b/iam_policies/9-1-deny-access-to-any-gateway-attachment.json new file mode 100644 index 0000000..85f288d --- /dev/null +++ b/iam_policies/9-1-deny-access-to-any-gateway-attachment.json @@ -0,0 +1,17 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Deny", + "Action": [ + "ec2:AcceptVpcPeeringConnection", + "ec2:CreateInternetGateway", + "ec2:AttachInternetGateway", + "ec2:CreateEgressOnlyInternetGateway", + "ec2:CreateVpcPeeringConnection" + ], + "Resource": "*" + } + ] +} diff --git a/jenkins-terraform-pipeline/ec2_pipeline/Jenkinsfile b/jenkins-terraform-pipeline/ec2_pipeline/Jenkinsfile index b0d99cd..6e4d71f 100644 --- a/jenkins-terraform-pipeline/ec2_pipeline/Jenkinsfile +++ b/jenkins-terraform-pipeline/ec2_pipeline/Jenkinsfile @@ -1,14 +1,14 @@ pipeline { agent any tools { - "org.jenkinsci.plugins.terraform.TerraformInstallation" "terraform-0.11.8" + "org.jenkinsci.plugins.terraform.TerraformInstallation" "terraform" } parameters { string(name: 'WORKSPACE', defaultValue: 'development', description:'setting up workspace for terraform') } environment { - TF_HOME = tool('terraform-0.11.8') - TF_IN_AUTOMATION = "true" + TF_HOME = tool('terraform') + TP_LOG = "WARN" PATH = "$TF_HOME:$PATH" ACCESS_KEY = credentials('AWS_ACCESS_KEY_ID') SECRET_KEY = credentials('AWS_SECRET_ACCESS_KEY') @@ -56,6 +56,7 @@ pipeline { } } } + stage('TerraformApply'){ steps { script{ @@ -70,7 +71,7 @@ pipeline { if(apply){ dir('jenkins-terraform-pipeline/ec2_pipeline/'){ unstash "terraform-plan" - sh 'terraform apply terraform.tfplan' + sh 'terraform apply terraform.tfplan' } } } diff --git a/jenkins-terraform-pipeline/ec2_pipeline/main.tf b/jenkins-terraform-pipeline/ec2_pipeline/main.tf index eb3c1f5..757c4f1 100644 --- a/jenkins-terraform-pipeline/ec2_pipeline/main.tf +++ b/jenkins-terraform-pipeline/ec2_pipeline/main.tf @@ -3,6 +3,6 @@ provider "aws" { } resource "aws_instance" "example" { - ami = "ami-01ed306a12b7d1c96" - instance_type = "t2.medium" + ami = "ami-0721c9af7b9b75114" + instance_type = "t2.nano" } diff --git a/jenkins-terraform-pipeline/ec2_pipeline/variables.tf b/jenkins-terraform-pipeline/ec2_pipeline/variables.tf new file mode 100644 index 0000000..df43f8a --- /dev/null +++ b/jenkins-terraform-pipeline/ec2_pipeline/variables.tf @@ -0,0 +1,6 @@ +variable "access_key" { + type = string +} +variable "secret_key" { + type = string +} diff --git a/jenkins_testenv/helloworld.sh b/jenkins_testenv/helloworld.sh new file mode 100644 index 0000000..b1e4199 --- /dev/null +++ b/jenkins_testenv/helloworld.sh @@ -0,0 +1 @@ +echo "hello world" diff --git a/kind/multi-node-master.yaml b/kind/multi-node-master.yaml new file mode 100644 index 0000000..4953241 --- /dev/null +++ b/kind/multi-node-master.yaml @@ -0,0 +1,7 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: control-plane +- role: worker +- role: worker diff --git a/kind/single-node-master.yaml b/kind/single-node-master.yaml new file mode 100644 index 0000000..752e993 --- /dev/null +++ b/kind/single-node-master.yaml @@ -0,0 +1,6 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker +- role: worker diff --git a/kubernetes_debugging/container_creating_error.sh b/kubernetes_debugging/container_creating_error.sh new file mode 100755 index 0000000..468338a --- /dev/null +++ b/kubernetes_debugging/container_creating_error.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Script to check ContainerCreating error in Kubernetes pods +# Author: Prashant Lakhera(laprashant@gmail.com) + +# Set the namespace which we use to query the pods +namespace="default" + +# Query for the pods using the namespace +pods=$(kubectl get pods -n "$namespace" -o json | jq -r '.items[].metadata.name') + +# Iterate through the list of pods +for pod in $pods; do + # Get the status of the current pod + status=$(kubectl get pod "$pod" -n "$namespace" -o json | jq -r '.status.containerStatuses[].state.waiting.reason') + # Check if the status is "ContainerCreating" + if [ "$status" == "ContainerCreating" ]; then + # Print an error message + echo "ERROR: Pod $pod is in a ContainerCreating state!" + exit 1 + # In some cases this is helpful,try to delete the pod to allow it to be rescheduled + # kubectl delete pod "$pod" -n "$namespace" + fi +done + + diff --git a/kubernetes_debugging/crash_loopback_error.sh b/kubernetes_debugging/crash_loopback_error.sh new file mode 100755 index 0000000..6841637 --- /dev/null +++ b/kubernetes_debugging/crash_loopback_error.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Script to check Crashloopbackoff error in Kubernetes pods +# Author: Prashant Lakhera(laprashant@gmail.com) + +# Set the namespace which we use to query the pods +namespace="default" + +# Query for the pods using the namespace +pods=$(kubectl get pods -n "$namespace" -o json | jq -r '.items[].metadata.name') + +# Iterate through the list of pods +for pod in $pods; do + # Get the status of the current pod + status=$(kubectl describe pod "$pod" -n "$namespace"| grep "CrashLoopBackOff" |awk '{print $2}') + + # If the status is "CrashLoopBackOff", handle the error + for state in status + do + if [ "$status" == "CrashLoopBackOff" ]; then + # Print an error message + echo "ERROR: Pod $pod is in a CrashLoopBackOff state!" + exit 1 + + # Try to delete the pod to allow it to be rescheduled + #kubectl delete pod "$pod" -n "$namespace" + + # Print a message indicating that the pod was deleted + #echo "INFO: Deleted pod $pod to allow it to be rescheduled." + fi + done +done diff --git a/kubernetes_debugging/create_container_config.sh b/kubernetes_debugging/create_container_config.sh new file mode 100755 index 0000000..fdc2a3d --- /dev/null +++ b/kubernetes_debugging/create_container_config.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Script to check ContainerCreating error in Kubernetes pods +# Author: Prashant Lakhera(laprashant@gmail.com) + +# Set the namespace which we use to query the pods +namespace="default" + +# Query for the pods using the namespace +pods=$(kubectl get pods -n "$namespace" -o json | jq -r '.items[].metadata.name') + +# Iterate through the list of pods +for pod in $pods; do + # Get the status of the current pod + status=$(kubectl describe pod "$pod" -n "$namespace" | grep "CreateContainerConfigError" | awk '{print $2}') + # If the status of the pod contains the "CreateContainerConfig" error + if [[ "$status" = "CreateContainerConfigError" ]]; then + # Print an error message + echo "ERROR: Pod $pod has a CreateContainerConfig error!" + exit 1 + + # In some cases,Try to delete the pod to allow it to be rescheduled + # kubectl delete pod "$pod" -n "$namespace" + fi +done \ No newline at end of file diff --git a/kubernetes_debugging/kubernetes_debugging_select.sh b/kubernetes_debugging/kubernetes_debugging_select.sh new file mode 100755 index 0000000..ec77de5 --- /dev/null +++ b/kubernetes_debugging/kubernetes_debugging_select.sh @@ -0,0 +1,31 @@ +# Create a list of options for Kubernetes Debugging +options=("CrashLoopBackOff" "ImagePullBackOff" "ContainerCreating" "CreateContainerConfigError" "Quit") + +# Display the menu and prompt the user to select an option +echo "Please select from the following Kubernetes Debugging option" +PS3="Please select an option: " +select opt in "${options[@]}"; do + # Process the user's selection + case $opt in + "CrashLoopBackOff") + # Execute crash_loopback_error.sh + source crash_loopback_error.sh + ;; + "ImagePullBackOff") + # Execute pod_image_pull_error.sh + source pod_image_pull_error.sh + ;; + "ContainerCreating") + # Execute container_creating_error.sh + source container_creating_error.sh + ;; + "CreateContainerConfigError") + # Execute create_container_config.sh + source create_container_config.sh + ;; + "Quit") + break + ;; + *) echo "Invalid option. Please try again.";; + esac +done diff --git a/kubernetes_debugging/pod_image_pull_error.sh b/kubernetes_debugging/pod_image_pull_error.sh new file mode 100755 index 0000000..630eabd --- /dev/null +++ b/kubernetes_debugging/pod_image_pull_error.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Script to check image pull error in Kubernetes pods +# Author: Prashant Lakhera(laprashant@gmail.com) + +# Set the namespace which we use to query the pods +NAMESPACE=default + +# Query for the pods using the namespace and label selector +PODS=$(kubectl get pods -n $NAMESPACE -o json) + +# Verify if the query return any pods +if [ -z "$PODS" ]; then + echo "No pods found" + exit 0 +fi + +# Parse the JSON output to get the list of pod names +POD_NAMES=$(echo $PODS | jq -r '.items[].metadata.name') + +# Iterate over the list of pod names +for POD_NAME in $POD_NAMES; do + # Check for image pull errors in the pod + IMAGE_PULL_ERRORS=$(kubectl describe pod $POD_NAME -n $NAMESPACE | grep -c "ImagePullBackOff") + + # If there is a image pull errors, print an error message and exit with an error code + if [ "$IMAGE_PULL_ERRORS" -gt 0 ]; then + echo "There were image pull errors in pod $POD_NAME" + fi +done + +# If there is no image pull error and all the pods are running, exit with a zero status code +exit 0 \ No newline at end of file diff --git a/metallb/cm.yaml b/metallb/cm.yaml new file mode 100644 index 0000000..f141498 --- /dev/null +++ b/metallb/cm.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: metallb-system + name: config +data: + config: | + address-pools: + - name: my-ip-space + protocol: layer2 + addresses: + - 172.18.0.200-172.18.0.250 #Add this range based on the output of kubectl get nodes -o wide diff --git a/paramiko/paramiko_test.py b/paramiko/paramiko_test.py new file mode 100644 index 0000000..74139a2 --- /dev/null +++ b/paramiko/paramiko_test.py @@ -0,0 +1,15 @@ +import paramiko +import time +import os + +password=os.environ.get('PASSWORD') + +ssh = paramiko.SSHClient() +ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +ssh.connect(hostname='44.X.X.X',username='centos',password=password) # export the password export PASSWORD='' in the shell +# If you want to connect using key +# ssh.connect(hostname='',username='centos',key_filename='') +stdin,stdout,stderr = ssh.exec_command('free -m') +time.sleep(5) +print(stdout.readlines()) +ssh.close() diff --git a/paramiko/uploading_downloading_the_file.py b/paramiko/uploading_downloading_the_file.py new file mode 100644 index 0000000..ec08314 --- /dev/null +++ b/paramiko/uploading_downloading_the_file.py @@ -0,0 +1,16 @@ +import paramiko +import time +import os + +password = os.environ.get('PASSWORD') + +ssh = paramiko.SSHClient() +ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +ssh.connect(hostname='44.X.X.X',username='centos',password=password) + +ftp_client=ssh.open_sftp() +ftp_client.put('myls.py','myls.py') +ftp_client.get('myls.py','/tmp/myls.py') + +ftp_client.put('myls.py','myls.py') +ftp_client.close() diff --git a/performance_tuning/performance-monitoring-simplified.sh b/performance_tuning/performance-monitoring-simplified.sh new file mode 100644 index 0000000..7984f04 --- /dev/null +++ b/performance_tuning/performance-monitoring-simplified.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# This script is the quick check to detect whether the performance issue is due to CPU, Memory, Input/Output (I/O), and network error +# This script should work on both CentOS and macOS +# Author: Prashant Lakhera(laprashant@gmail.com) + + +# Check if the load average is greater than 70% of the CPU cores +load_avg=$(w | head -n 1 | awk '{print $9}' |cut -f1 -d",") +num_cores=$(nproc) +max_load=$(echo "0.7 * $num_cores" | bc) + +if [[ $(echo "$load_avg > $max_load" | bc) -eq 1 ]]; then + #Print a message if the load average is too high + echo -e "\033[1;31m CPU load average is currently $load_avg, which is higher than the maximum of $max_load \033[0m" >&2 +else + # Print a message if the load average is within the acceptable range + echo -e "\033[1;32m CPU load average is currently $load_avg, which is within the acceptable range.\033[0m" +fi + +# Set the memory average threshold +THRESHOLD=90 + +# Get the total memory and used memory in bytes +total_memory=$(grep 'MemTotal' /proc/meminfo | awk '{print $2}') +available_memory=$(grep 'MemAvailable' /proc/meminfo | awk '{print $2}') + +# Calculate the actual memory utilization as a percentage +memory_utilization=$(echo "scale=2; ($total_memory - $available_memory)/$total_memory * 100" | bc) + +# Compare the memory utilization with the threshold +if (( $(echo "$memory_utilization > $THRESHOLD" | bc -l) )) +then + echo -e "\033[1;32m Memory utilization is above the threshold!!! Memory utilization is: $utilization% \033[0m" +else + echo -e "\033[1;32m Memory utilizationis currently $memory_utilization, which is within the acceptable range.\033[0m" +fi + +# Check the I/O wait state + +iowait_state=$(top -b -n 1 | head -n +3|awk '{print $10}'|tail -1 |bc) +if [[ $(echo "$iowait_state > 1" | bc) -eq 1 ]]; then + #Print a message IOWAIT is too high + echo -e "\033[1;31m IOWAIT is currently $iowait_state, which is higher than the acceptable range \033[0m" >&2 +else + # Print a message IOWAIT is within the acceptable range + echo -e "\033[1;32m IOWAIT is currently $iowait_state, which is within the acceptable range.\033[0m" +fi + +# Check if ifconfig command is present +if command -v ifconfig >/dev/null 2>&1; then + echo "ifconfig command is present" +else + echo "ifconfig command is not present. Installing..." + # Install ifconfig command + if [ -f /etc/centos-release ]; then + # CentOS + sudo yum install -y net-tools + elif [ -f /etc/lsb-release ]; then + # Ubuntu + sudo apt-get update + sudo apt-get install -y net-tools + else + # Unsupported OS + echo "Unsupported operating system" + exit 1 + fi +fi + +#Get the network interface name or ask input from the user +#interface=$1 +interface=$(ifconfig |head -1|awk '{print $1}' |cut -f1 -d:) + +# Get the RX error count +rx_error_count=$(ifconfig $interface | grep "RX errors" |awk '{print $3}') + +# Get the TX error count +tx_error_count=$(ifconfig $interface | grep "TX errors" |awk '{print $3}') + +# Check if either error count is greater than zero +# Remember these counter only get reset after reboot, so you may get some false alarm. Check this thread for more reference https://unix.stackexchange.com/questions/164057/how-can-i-manually-reset-rx-tx-counters-in-ifconfig-output-without-impacting-d +if [[ $rx_error_count -gt 0 || $tx_error_count -gt 0 ]]; then + #Print a message Network error count is too high + echo -e "\033[1;31m Network Error is currently for Revieve Error: $rx_error_count and Transmit Error: $tx_error_count, which is higher than the acceptable range \033[0m" >&2 +else + # Print a message Network error count is within the acceptable range + echo -e "\033[1;32m Network Error is currently for Revieve Error: $rx_error_count and Transmit Error: $tx_error_count, which is within the acceptable range.\033[0m" +fi \ No newline at end of file diff --git a/performance_tuning/performance-monitoring-v2.sh b/performance_tuning/performance-monitoring-v2.sh new file mode 100644 index 0000000..c76b204 --- /dev/null +++ b/performance_tuning/performance-monitoring-v2.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# This script list the top 5 CPU, memory, input/output (I/O), and network consuming processes +# This script should work on both CentOS and macOS +# Author: Prashant Lakhera(laprashant@gmail.com) + + +# Function to list top 5 CPU consuming process +list_top_cpu_consuming_processes() { + # Get the top 5 processes by CPU usage + top_five_cpu_processes=$(ps -eo pcpu,pid,user,args --no-headers | sort -k 1 -r | head -n 5) + + # Print the results + echo "###############################################################################" + echo "Top 5 CPU consuming processes:" + echo "$top_five_cpu_processes" +} + +# Function to list the top 5 processes by memory usage +list_top_memory_consuming_processes() { + # Get the top 5 processes by memory usage + top_five_memory_processes=$(ps -eo pmem,pid,user,args --no-headers | sort -k 1 -r | head -n 5) + + # Print the results + echo "###############################################################################" + echo "Top 5 memory consuming processes:" + echo "$top_five_memory_processes" +} + +# Check if iotop command is present +if command -v iotop >/dev/null 2>&1; then + echo "iotop command is present" +else + echo "iotop command is not present. Installing..." + # Install top command + if [ -f /etc/centos-release ]; then + # CentOS + sudo yum install -y epel-release + sudo yum install -y iotop + elif [ -f /etc/lsb-release ]; then + # Ubuntu + sudo apt-get update + sudo apt-get install -y iotop + else + # Unsupported OS + echo "Unsupported operating system" + exit 1 + fi +fi + +# Function to list the top 5 processes by I/O usage +list_top_io_consuming_processes() { + # Get the top 5 processes by I/O usage + top_five_io_processes=$(sudo iotop -o -b -n 5) + + # Print the results + echo "###############################################################################" + echo "Top 5 I/O consuming processes:" + echo "$top_five_io_processes" +} + +# Check if iftop command is present +if command -v iftop >/dev/null 2>&1; then + echo "iftop command is present" +else + echo "iftop command is not present. Installing..." + # Install top command + if [ -f /etc/centos-release ]; then + # CentOS + sudo yum install -y iftop + elif [ -f /etc/lsb-release ]; then + # Ubuntu + sudo apt-get update + sudo apt-get install -y iftop + else + # Unsupported OS + echo "Unsupported operating system" + exit 1 + fi +fi + + +# Function to list the top 5 processes by network usage +list_top_network_consuming_processes() { + # Get the top 5 processes by network usage + top_five_network_processes=$(sudo iftop -P -n -t -s 5) + + # Print the results + echo "###############################################################################" + echo "Top 5 network consuming processes:" + echo "$top_five_network_processes" +} + + +# Main function +main() { + list_top_cpu_consuming_processes + list_top_memory_consuming_processes + list_top_io_consuming_processes + list_top_network_consuming_processes +} + +# Run the main function +main diff --git a/performance_tuning/performance-monitoring.py b/performance_tuning/performance-monitoring.py new file mode 100644 index 0000000..7439e5d --- /dev/null +++ b/performance_tuning/performance-monitoring.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +import os + +# Function to list top 5 CPU consuming processes +def list_top_cpu_consuming_processes(): + # Get the top 5 processes by CPU usage + top_five_cpu_processes = os.popen("ps -eo pcpu,pid,user,args | sort -k 1 -r | head -n 6").read() + + # Print the results + print("###############################################################################") + print("Top 5 CPU consuming processes:") + print(top_five_cpu_processes) + +# Function to list the top 5 processes by memory usage +def list_top_memory_consuming_processes(): + # Get the top 5 processes by memory usage + top_five_memory_processes = os.popen("ps -eo pmem,pid,user,args | sort -k 1 -r | head -n 6").read() + + # Print the results + print("###############################################################################") + print("Top 5 memory consuming processes:") + print(top_five_memory_processes) + +# Check if iotop command is present +if os.system("command -v iotop >/dev/null 2>&1") == 0: + print("iotop command is present") +else: + print("iotop command is not present. Installing...") + # Install iotop command + if os.path.isfile("/etc/centos-release"): + # CentOS + os.system("sudo yum install -y epel-release") + os.system("sudo yum install -y iotop") + elif os.path.isfile("/etc/lsb-release"): + # Ubuntu + os.system("sudo apt-get update") + os.system("sudo apt-get install -y iotop") + else: + # Unsupported OS + print("Unsupported operating system") + exit(1) + +# Function to list the top 5 processes by I/O usage +def list_top_io_consuming_processes(): + # Get the top 5 processes by I/O usage + top_five_io_processes = os.popen("sudo iotop -o -b -n 6").read() + + # Print the results + print("###############################################################################") + print("Top 5 I/O consuming processes:") + print(top_five_io_processes) + +# Check if iftop command is present +if os.system("command -v iftop >/dev/null 2>&1") == 0: + print("iftop command is present") +else: + print("iftop command is not present. Installing...") + # Install iftop command + if os.path.isfile("/etc/centos-release"): + # CentOS + os.system("sudo yum install -y iftop") + elif os.path.isfile("/etc/lsb-release"): + # Ubuntu + os.system("sudo apt-get update") + os.system("sudo apt-get install -y iftop") + else: + # Unsupported OS + print("Unsupported operating system") + exit(1) + +# Function to list the top 5 processes by network usage +def list_top_network_consuming_processes(): + # Get the top 5 processes by network usage + top_five_network_processes = os.popen("sudo iftop -P -n -t -s 6").read() + + # Print the results + print("###############################################################################") + print("Top 5 network consuming processes:") + print(top_five_network_processes) + +# Main function +def main(): + list_top_cpu_consuming_processes() + list_top_memory_consuming_processes() + list_top_io_consuming_processes() + list_top_network_consuming_processes() + +# Run the main function +if __name__ == "__main__": + main() diff --git a/performance_tuning/performance-monitoring.sh b/performance_tuning/performance-monitoring.sh new file mode 100644 index 0000000..7d74976 --- /dev/null +++ b/performance_tuning/performance-monitoring.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# This script list the top 5 CPU, memory, input/output (I/O), and network consuming processes +# This script should work on both CentOS and macOS +# Author: Prashant Lakhera(laprashant@gmail.com) + + +# Function to list top 5 CPU consuming process +list_top_cpu_consuming_processes() { + # Get the top 5 processes by CPU usage + top_five_cpu_processes=$(ps -eo pcpu,pid,user,args | sort -k 1 -r | head -n 6) + + # Print the results + echo "###############################################################################" + echo "Top 5 CPU consuming processes:" + echo "$top_five_cpu_processes" +} + +# Function to list the top 5 processes by memory usage +list_top_memory_consuming_processes() { + # Get the top 5 processes by memory usage + top_five_memory_processes=$(ps -eo pmem,pid,user,args | sort -k 1 -r | head -n 6) + + # Print the results + echo "###############################################################################" + echo "Top 5 memory consuming processes:" + echo "$top_five_memory_processes" +} + +# Check if iotop command is present +if command -v iotop >/dev/null 2>&1; then + echo "iotop command is present" +else + echo "iotop command is not present. Installing..." + # Install top command + if [ -f /etc/centos-release ]; then + # CentOS + sudo yum install -y epel-release + sudo yum install -y iotop + elif [ -f /etc/lsb-release ]; then + # Ubuntu + sudo apt-get update + sudo apt-get install -y iotop + else + # Unsupported OS + echo "Unsupported operating system" + exit 1 + fi +fi + +# Function to list the top 5 processes by I/O usage +list_top_io_consuming_processes() { + # Get the top 5 processes by I/O usage + top_five_io_processes=$(sudo iotop -o -b -n 6) + + # Print the results + echo "###############################################################################" + echo "Top 5 I/O consuming processes:" + echo "$top_five_io_processes" +} + +# Check if iftop command is present +if command -v iftop >/dev/null 2>&1; then + echo "iftop command is present" +else + echo "iftop command is not present. Installing..." + # Install top command + if [ -f /etc/centos-release ]; then + # CentOS + sudo yum install -y iftop + elif [ -f /etc/lsb-release ]; then + # Ubuntu + sudo apt-get update + sudo apt-get install -y iftop + else + # Unsupported OS + echo "Unsupported operating system" + exit 1 + fi +fi + + +# Function to list the top 5 processes by network usage +list_top_network_consuming_processes() { + # Get the top 5 processes by network usage + top_five_network_processes=$(sudo iftop -P -n -t -s 6) + + # Print the results + echo "###############################################################################" + echo "Top 5 network consuming processes:" + echo "$top_five_network_processes" +} + + +# Main function +main() { + list_top_cpu_consuming_processes + list_top_memory_consuming_processes + list_top_io_consuming_processes + list_top_network_consuming_processes +} + +# Run the main function +main diff --git a/platform/platform_module.py b/platform/platform_module.py new file mode 100644 index 0000000..a4c1778 --- /dev/null +++ b/platform/platform_module.py @@ -0,0 +1,10 @@ +import platform +import os + + +if platform.system() == 'Linux': + os.system("ls") +elif platform.system() == 'Windows': + os.system("dir") +else: + print("Unsupported operating system") diff --git a/python_script_to_check_website_status/script_to_check_website_status.py b/python_script_to_check_website_status/script_to_check_website_status.py new file mode 100644 index 0000000..366d861 --- /dev/null +++ b/python_script_to_check_website_status/script_to_check_website_status.py @@ -0,0 +1,33 @@ +import requests +import bs4 +import smtplib +import os + +email_add = os.environ.get('EMAIL_ADD') +password = os.environ.get('EMAIL_PASS') + +def send_email(): + s = smtplib.SMTP('smtp.gmail.com', 587) + s.starttls() + s.login(email_add, password) + subject = "!!!!!! 100 days of devops site is down" + body = "Check the status of 100 days of devops" + message = f'Subject: {subject}\n\n {body}' + s.sendmail(email_add, email_add, message) + s.quit() + + +producturl="http://100daysofdevops.com/contact-us/" + +res = requests.get(producturl, timeout=5) +if res.status_code != 200: + send_email() + +soup = bs4.BeautifulSoup(res.text,'html.parser') + +elems = soup.select('#post-67 > div > div > header > h2') +try: + if elems[0].text != "Welcome": + send_email() +except Exception as e: + send_email() diff --git a/search_for_file/search_for_file.py b/search_for_file/search_for_file.py new file mode 100644 index 0000000..6a6ba9e --- /dev/null +++ b/search_for_file/search_for_file.py @@ -0,0 +1,17 @@ +import os +import argparse + +my_parser = argparse.ArgumentParser(description='Reading the directory path to find the file') +my_parser.add_argument("pathname", + help='Please enter the directory path ') +my_parser.add_argument("filesearch", + help='Please enter the filename to search') +args = my_parser.parse_args() + +for dirname, dirpath, filename in os.walk(args.pathname): + for file in filename: + if file == args.filesearch: + print(os.path.join(dirname,file)) + + + diff --git a/search_for_file/search_for_file_with_extension.py b/search_for_file/search_for_file_with_extension.py new file mode 100644 index 0000000..b3f09c7 --- /dev/null +++ b/search_for_file/search_for_file_with_extension.py @@ -0,0 +1,15 @@ +import os +import argparse + +my_parser = argparse.ArgumentParser(description='Reading the directory path to find the file') +my_parser.add_argument("pathname", + help='Please enter the directory path ') +args = my_parser.parse_args() + +for dirname, dirpath, filename in os.walk(args.pathname): + for file in filename: + if file.endswith('.conf'): + print(os.path.join(dirname,file)) + + + diff --git a/sns_ses_to_sendemail/sns_ses_to_sendemail.py b/sns_ses_to_sendemail/sns_ses_to_sendemail.py new file mode 100644 index 0000000..40acec0 --- /dev/null +++ b/sns_ses_to_sendemail/sns_ses_to_sendemail.py @@ -0,0 +1,35 @@ +import boto3 + +client = boto3.client('sns') + +ses = boto3.client('ses') + +response = client.create_topic( + Name='my-test-topic') + +response = client.subscribe( + TopicArn='arn:aws:sns:us-west-2:XXXXXXXXX:my-test-topic', + Protocol='email', + Endpoint='102daysofdevops@gmail.com', + ReturnSubscriptionArn=True +) + +response = client.publish(TopicArn='arn:aws:sns:us-west-2:XXXXXX:my-test-topic',Message="Hello from aws") +print(response) + +response = ses.send_email( + Source=EMAIL_FROM, + Destination={ + 'ToAddresses': [EMAIL_TO] + }, + Message={ + 'Subject': { + 'Data': ('Cleanup following Volume ' + f'Volume: {vol_id}') + }, + 'Body': { + 'Text': { + 'Data': data + } + } + })