Skip to content

Commit

Permalink
Updates for Fall 2021
Browse files Browse the repository at this point in the history
  • Loading branch information
rofrano committed Nov 24, 2021
1 parent 09c26ed commit b546657
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 229 deletions.
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
FROM python:3.8-slim
FROM python:3.9-slim

# Create working folder and install dependencies
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install -U pip wheel && \
pip install --no-cache-dir -r requirements.txt

# Copy the application contents
COPY service/ ./service/

# Switch to a non-root user
RUN useradd appuser && chown -R appuser /app
USER appuser
RUN useradd --uid 1000 vagrant && chown -R vagrant /app
USER vagrant

# Expose any ports the app is expecting in the environment
ENV FLASK_APP=service:app
ENV PORT 8080
EXPOSE $PORT

ENV GUNICORN_BIND 0.0.0.0:$PORT
CMD ["gunicorn", "--log-level=info", "service:app"]
ENTRYPOINT ["gunicorn"]
CMD ["--log-level=info", "service:app"]
161 changes: 69 additions & 92 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
# Kubernetes Minikube Environment
######################################################################
Vagrant.configure(2) do |config|
# config.vm.box = "bento/ubuntu-20.04"
config.vm.box = "ubuntu/focal64"
config.vm.hostname = "kubernetes"
# config.vm.box = "ubuntu/focal64"
# config.vm.hostname = "ubuntu"
# config.vm.box = "debian/buster64"
# config.vm.box = "debian/bullseye64"
config.vm.box = "bento/ubuntu-21.04"
config.vm.hostname = "kubernetes"

# config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "forwarded_port", guest: 8090, host: 8090, host_ip: "127.0.0.1"
config.vm.network "forwarded_port", guest: 8080, host: 8080, host_ip: "127.0.0.1"

# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.network "private_network", ip: "192.168.56.10"

# Mac users can comment this next line out but
# Windows users need to change the permission of files and directories
Expand All @@ -29,16 +32,16 @@ Vagrant.configure(2) do |config|
vb.memory = "4096"
vb.cpus = 2
# Fixes some DNS issues on some networks
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
#vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
#vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end

############################################################
# Configure Vagrant to use for Docker on Intel or ARM
############################################################
config.vm.provider :docker do |docker, override|
override.vm.box = nil
docker.image = "rofrano/vagrant-provider:ubuntu"
docker.image = "rofrano/vagrant-provider:debian"
docker.remains_running = true
docker.has_ssh = true
docker.privileged = true
Expand Down Expand Up @@ -66,9 +69,9 @@ Vagrant.configure(2) do |config|
config.vm.provision "file", source: "~/.vimrc", destination: "~/.vimrc"
end

# Copy your IBM Clouid API Key if you have one
if File.exists?(File.expand_path("~/.bluemix/apiKey.json"))
config.vm.provision "file", source: "~/.bluemix/apiKey.json", destination: "~/.bluemix/apiKey.json"
# Copy your IBM Cloud API Key if you have one
if File.exists?(File.expand_path("~/.bluemix/apikey.json"))
config.vm.provision "file", source: "~/.bluemix/apikey.json", destination: "~/.bluemix/apikey.json"
end

######################################################################
Expand All @@ -77,113 +80,87 @@ Vagrant.configure(2) do |config|
config.vm.provision "shell", inline: <<-SHELL
# Install Python 3 and dev tools
apt-get update
apt-get install -y git vim tree wget jq build-essential python3-dev python3-pip python3-venv apt-transport-https
apt-get install -y git vim tree wget jq python3-dev python3-pip python3-venv apt-transport-https
apt-get upgrade python3
# Create a Python3 Virtual Environment and Activate it in .profile
sudo -H -u vagrant sh -c 'python3 -m venv ~/venv'
sudo -H -u vagrant sh -c 'echo ". ~/venv/bin/activate" >> ~/.profile'
# Install app dependencies in virtual environment as vagrant user
sudo -H -u vagrant sh -c '. ~/venv/bin/activate && pip install -U pip && pip install wheel'
sudo -H -u vagrant sh -c '. ~/venv/bin/activate && pip install docker-compose'
sudo -H -u vagrant sh -c '. ~/venv/bin/activate && cd /vagrant && pip install -r requirements.txt'
sudo -H -u vagrant sh -c '. ~/venv/bin/activate &&
cd /vagrant &&
pip install -U pip wheel &&
pip install docker-compose &&
pip install -r requirements.txt'
# Check versions to prove that everything is installed
python3 --version
# Check versions to prove that everything is installed
python3 --version
# Create .env file if it doesn't exist
sudo -H -u vagrant sh -c 'cd /vagrant && if [ ! -f .env ]; then cp dot-env-example .env; fi'
SHELL

############################################################
# Provision Docker with Vagrant before starting kubernetes
############################################################
config.vm.provision "docker" do |d|
d.pull_images "alpine"
d.pull_images "python:3.8-slim"
d.pull_images "python:3.9-slim"
d.pull_images "redis:6-alpine"
d.run "redis:6-alpine",
args: "--restart=always -d --name redis -p 6379:6379 -v redis:/data"
end

# ############################################################
# # Install Kuberrnetes CLI
# ############################################################
# config.vm.provision "shell", inline: <<-SHELL
# # Install kubectl
# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/$(dpkg --print-architecture)/kubectl"
# install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# rm kubectl
# echo "alias kc='/usr/local/bin/kubectl'" >> /home/vagrant/.bash_aliases
# chown vagrant:vagrant /home/vagrant/.bash_aliases
# SHELL
############################################################
# Install Kubernetes CLI and Helm
############################################################
config.vm.provision "shell", inline: <<-SHELL
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/$(dpkg --print-architecture)/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
rm kubectl
echo "alias kc='/usr/local/bin/kubectl'" >> /home/vagrant/.bash_aliases
chown vagrant:vagrant /home/vagrant/.bash_aliases
# Install helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
SHELL

# ############################################################
# # Create a Kubernetes Cluster wiith K3D
# ############################################################
# config.vm.provision "shell", inline: <<-SHELL
# # Install K3d
# curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
# sudo -H -u vagrant sh -c "k3d registry create registry.localhost --port 50000"
# sudo -H -u vagrant sh -c "k3d cluster create mycluster --registry-use k3d-registry.localhost:50000 --agents 1 --port '8080:80@loadbalancer'"
# SHELL

############################################################
# Create a Kubernetes Cluster with MicroK8s
# Create a Kubernetes Cluster wiith K3D
############################################################
config.vm.provision "shell", inline: <<-SHELL
# install MicroK8s version of Kubernetes
sudo snap install microk8s --classic
sudo microk8s.enable dns
sudo microk8s.enable dashboard
sudo microk8s.enable ingress
sudo microk8s.enable registry
sudo usermod -a -G microk8s vagrant
sudo -H -u vagrant sh -c 'echo "alias kubectl=/snap/bin/microk8s.kubectl" >> ~/.bashrc'
/snap/bin/microk8s.kubectl version --short
# # Create aliases for microk8s=mk and kubecl=kc
# echo "alias mk='/snap/bin/microk8s'" >> /home/vagrant/.bash_aliases
# #echo "alias kc='/snap/bin/kubectl'" >> /home/vagrant/.bash_aliases
# chown vagrant:vagrant /home/vagrant/.bash_aliases
# # Set up Kubernetes context
# sudo -H -u vagrant sh -c 'mkdir ~/.kube && microk8s.kubectl config view --raw > ~/.kube/config'
# kubectl version --short
# microk8s.config > /home/vagrant/.kube/config
# chown vagrant:vagrant /home/vagrant/.kube/config
# chmod 600 /home/vagrant/.kube/config
# Install K3d
curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
# echo "127.0.0.1 k3d-registry.localhost" >> /etc/hosts
# sudo -H -u vagrant sh -c "k3d registry create registry.localhost --port 50000"
# sudo -H -u vagrant sh -c "k3d cluster create devops --registry-use k3d-registry.localhost:50000 --agents 1 --port '8080:80@loadbalancer'"
SHELL

# ######################################################################
# # Setup an IBM Cloud and Kubernetes environment
# ######################################################################
# config.vm.provision "shell", inline: <<-SHELL
# echo "\n************************************"
# echo " Installing IBM Cloud CLI..."
# echo "************************************\n"
# # Install IBM Cloud CLI as Vagrant user
# sudo -H -u vagrant sh -c 'curl -sL https://ibm.biz/idt-installer | bash'
# sudo -H -u vagrant sh -c 'ibmcloud config --usage-stats-collect false'
# sudo -H -u vagrant sh -c "echo 'source <(kubectl completion bash)' >> ~/.bashrc"
# sudo -H -u vagrant sh -c "echo alias ic=/usr/local/bin/ibmcloud >> ~/.bash_aliases"
# # Install OpenShift Client (optional)
# # mkdir ./openshift-client
# # cd openshift-client
# # wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest/openshift-client-linux.tar.gz
# # tar xzf openshift-client-linux.tar.gz
# # cp kubectl /usr/local/bin
# # cp oc /usr/local/bin
# # cd ..
# # rmdir -fr ./openshift-client
# #
# # Install the IBM Cloud Native Toolkit
# # curl -sL shell.cloudnativetoolkit.dev | sh - && . ~/.bashrc
# echo "\n"
# echo "\n************************************"
# echo " For the Kubernetes Dashboard use:"
# echo " kubectl proxy --address='0.0.0.0'"
# echo "************************************\n"
# # Prove that plug-ins are installed as vagrant user
# sudo -H -u vagrant bash -c "bx plugin list"
# SHELL
######################################################################
# Setup a IBM Cloud and Kubernetes environment
######################################################################
config.vm.provision "shell", inline: <<-SHELL
echo "\n************************************"
echo " Installing IBM Cloud CLI..."
echo "************************************\n"
# Install IBM Cloud CLI as Vagrant user
sudo -H -u vagrant sh -c '
curl -fsSL https://clis.cloud.ibm.com/install/linux | sh && \
ibmcloud plugin install container-service && \
ibmcloud plugin install container-registry && \
echo "alias ic=ibmcloud" >> ~/.bashrc
'
# Show completion instructions
sudo -H -u vagrant sh -c "echo alias ic=/usr/local/bin/ibmcloud >> ~/.bash_aliases"
echo "\n************************************"
echo "If you have an IBM Cloud API key in ~/.bluemix/apiKey.json"
echo "You can login with the following command:"
echo "\n"
echo "ibmcloud login -a https://cloud.ibm.com --apikey @~/.bluemix/apikey.json -r us-south"
echo "ibmcloud ks cluster config --cluster <your-cluster-name>"
echo "\n************************************"
SHELL

end
4 changes: 1 addition & 3 deletions deploy/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ spec:
restartPolicy: Always
containers:
- name: hitcounter
# image: localhost:32000/hitcounter:1.0
# image: k3d-registry.localhost:50000/hitcounter:1.0
image: hitcounter:1.0
image: cluster-registry:32000/hitcounter:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
Expand Down
2 changes: 2 additions & 0 deletions dot-env-example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PORT=8080
FLASK_APP=service:app
28 changes: 11 additions & 17 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
# Lock down these dependencies
Werkzeug==1.0.1

# Developmeent
Flask==1.1.2
Flask-API==1.1
# Runtime dependencies
Flask==2.0.2
redis==3.5.3
python-dotenv==0.15.0

# Runtime
gunicorn==20.0.4
honcho==1.0.1
httpie==1.0.3
gunicorn==20.1.0
honcho==1.1.0
python-dotenv==0.19.2

# Testing
# Testing dependencies
nose==1.3.7
pinocchio==0.4.2
coverage==4.5.4
codecov==2.0.15
pylint>=2.4.1
pinocchio==0.4.3
coverage==6.1.2
codecov==2.1.12
httpie==2.6.0
pylint==2.11.1
4 changes: 4 additions & 0 deletions scripts/create-cluster.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
echo "Creating Kubernetes cluster with a registry..."
k3d cluster create --registry-create cluster-registry:0.0.0.0:32000 --port '8080:80@loadbalancer'
echo "Complete."
4 changes: 4 additions & 0 deletions scripts/delete-cluster.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
echo "Deleting Kubernetes cluster..."
k3d cluster delete
echo "Complete."
4 changes: 2 additions & 2 deletions service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
app = Flask(__name__)

# Import the routes After the Flask app is created
from service import routes, models
from service import routes, models, error_handlers

# Set up logging for production
app.logger.propagate = False
Expand All @@ -43,4 +43,4 @@
app.logger.info(" H I T C O U N T E R S E R V I C E ".center(70, "*"))
app.logger.info(70 * "*")

app.logger.info("Service inititalized!")
app.logger.info("Service initialized!")
60 changes: 60 additions & 0 deletions service/error_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from flask import jsonify
from . import app, status

######################################################################
# Error Handlers
######################################################################

@app.errorhandler(status.HTTP_404_NOT_FOUND)
def not_found(error):
""" Handles resources not found with 404_NOT_FOUND """
message = str(error)
app.logger.warning(message)
return (
jsonify(status=status.HTTP_404_NOT_FOUND, error="Not Found", message=message),
status.HTTP_404_NOT_FOUND,
)


@app.errorhandler(status.HTTP_405_METHOD_NOT_ALLOWED)
def method_not_supported(error):
""" Handles unsupported HTTP methods with 405_METHOD_NOT_SUPPORTED """
message = str(error)
app.logger.warning(message)
return (
jsonify(
status=status.HTTP_405_METHOD_NOT_ALLOWED,
error="Method not Allowed",
message=message,
),
status.HTTP_405_METHOD_NOT_ALLOWED,
)


@app.errorhandler(status.HTTP_500_INTERNAL_SERVER_ERROR)
def internal_server_error(error):
""" Handles unexpected server error with 500_SERVER_ERROR """
message = str(error)
app.logger.error(message)
return (
jsonify(
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
error="Internal Server Error",
message=message,
),
status.HTTP_500_INTERNAL_SERVER_ERROR,
)

@app.errorhandler(status.HTTP_503_SERVICE_UNAVAILABLE)
def service_unavailable(error):
""" Handles unexpected server error with 503_SERVICE_UNAVAILABLE """
message = str(error)
app.logger.error(message)
return (
jsonify(
status=status.HTTP_503_SERVICE_UNAVAILABLE,
error="Service is unavailable",
message=message,
),
status.HTTP_503_SERVICE_UNAVAILABLE,
)
Loading

0 comments on commit b546657

Please sign in to comment.