Skip to content

Commit

Permalink
various new tests and updates
Browse files Browse the repository at this point in the history
  • Loading branch information
alongir committed Nov 10, 2024
1 parent cdf863b commit 02358cb
Show file tree
Hide file tree
Showing 13 changed files with 293 additions and 53 deletions.
23 changes: 21 additions & 2 deletions additions/websocket-client/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
# Step 1: Use the Python 3.8 slim base image
FROM python:3.8-slim-buster

# Step 2: Set the working directory inside the container
WORKDIR /app

# Step 3: Copy the requirements file and install Python dependencies
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
RUN apt-get update
RUN apt-get -y install curl procps

# Step 4: Install curl, procps, Node.js (for wscat), and iputils-ping
RUN apt-get update && apt-get install -y \
curl \
procps \
nodejs \
npm \
iputils-ping \
&& npm install -g wscat

# Step 5: Copy the application code and scripts
COPY example.py .
COPY run.sh .

# Step 6: Make sure run.sh is executable
RUN chmod +x ./run.sh

# Step 7: Set the entry point
CMD ["./run.sh"]
64 changes: 48 additions & 16 deletions additions/websocket-client/example.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,64 @@
import websocket
import time
import argparse

def connect():
try:
ws = websocket.WebSocket()
ws.connect("ws://echo.websocket.events")
return ws
except Exception as e:
print(f"Error connecting to WebSocket: {e}")
return None
# Function to connect to the WebSocket server
def connect(server_url, use_compression):
while True:
try:
headers = []

# Include the compression extension if requested
if use_compression:
headers.append("Sec-WebSocket-Extensions: permessage-deflate")

ws = websocket.WebSocket()
ws.connect(server_url, header=headers) # Use the server URL passed as an argument

print(f"Connected to WebSocket server {server_url} (Compression: {use_compression})")
return ws
except Exception as e:
print(f"Error connecting to WebSocket: {e}. Retrying in 30 seconds...")
time.sleep(30) # Wait 30 seconds before retrying

def run():
ws = connect()

# Function to send and receive messages
def run(server_url, use_compression):
ws = connect(server_url, use_compression=use_compression)
message_count = 1 # Start the message counter at 1
while ws:
while True:
try:
message = f"Hello, Server (Message {message_count})"
ws.send(message)
print(f"Sent: {message}")
response = ws.recv()
print(f"Received: {response}")
message_count += 1 # Increment the message counter
time.sleep(3)
time.sleep(3) # Wait 3 seconds between messages
except Exception as e:
print(f"Error during communication: {e}")
print(f"Error during communication: {e}. Reconnecting...")
ws.close()
print("Attempting to reconnect...")
ws = connect()
ws = connect(server_url, use_compression=use_compression)

if __name__ == "__main__":
run()
# Set up argparse
parser = argparse.ArgumentParser(description="WebSocket client with optional compression")
parser.add_argument(
"--server",
type=str,
required=True,
help="WebSocket server URL (e.g., ws://websocket-server-service.sock-shop.svc.cluster.local:80)"
)
parser.add_argument(
"--compressed",
type=str,
choices=["true", "false"],
default="false",
help="Enable WebSocket compression"
)

args = parser.parse_args()
server_url = args.server # Get the server URL from the argument
use_compression = args.compressed.lower() == "true"

run(server_url, use_compression)
17 changes: 15 additions & 2 deletions additions/websocket-client/run.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
#!/bin/bash
#!/bin/sh

python3 -u example.py
# Ensure that the script fails on errors
set -e

# Default values for variables
COMPRESSED=${COMPRESSED:-false}
SERVER_URL=${SERVER_URL:-"ws://websocket-server-service.sock-shop.svc.cluster.local:80"}

# Log the start of the client
echo "Starting WebSocket client..."
echo "Connecting to server: $SERVER_URL"
echo "Compression enabled: $COMPRESSED"

# Run the WebSocket client with the provided options
python example.py --server "$SERVER_URL" --compressed "$COMPRESSED"
30 changes: 30 additions & 0 deletions additions/websocket-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Step 1: Use a lightweight Python 3.10 base image
FROM python:3.10-slim

# Step 2: Set a working directory inside the container
WORKDIR /app

# Step 3: Copy the requirements.txt file into the container
COPY requirements.txt .

# Step 4: Install Python dependencies from requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Step 5: Install curl, procps, Node.js (for wscat), iputils-ping, and net-tools (for netstat)
RUN apt-get update && apt-get install -y \
curl \
procps \
nodejs \
npm \
iputils-ping \
net-tools \
&& npm install -g wscat

# Step 6: Copy the application code into the container
COPY . .

# Step 7: Expose the port your application will use (default port, can be overridden)
EXPOSE 80

# Step 8: Use an environment variable for the port, with a default value (80), and pass it to the server.py script
CMD ["sh", "-c", "python server.py --port ${PORT:-80}"]
21 changes: 21 additions & 0 deletions additions/websocket-server/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

# Define variables
IMAGE_NAME="kubeshark/mizutest-websocket-server"
VERSION=${1:-latest} # Use the provided version or default to 'latest'
PORT=${2:-80} # Use provided port or default to 8765

# Ensure Docker Buildx is available and use it
echo "Ensuring Docker Buildx is set up..."
docker buildx create --use || docker buildx use default

# Build the multi-platform image (AMD64 and ARM64) and push it to the registry
echo "Building and pushing Docker image for AMD64 and ARM64 architectures..."
docker buildx build --platform linux/amd64,linux/arm64 -t $IMAGE_NAME:$VERSION . --push

echo "Docker image $IMAGE_NAME:$VERSION built and pushed successfully!"

# Run the container (optional step)
# Uncomment to run the container with the specified port
# echo "Running Docker container on port $PORT..."
# docker run -d -p $PORT:$PORT -e PORT=$PORT $IMAGE_NAME:$VERSION
1 change: 1 addition & 0 deletions additions/websocket-server/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
websockets==13.1
40 changes: 40 additions & 0 deletions additions/websocket-server/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import asyncio
import websockets
import argparse

# WebSocket server handler
async def echo(websocket, path):
print(f"New connection from: {websocket.remote_address}, Compression: {websocket.extensions}")

try:
async for message in websocket:
print(f"Received message: {message}")
await websocket.send(f"Echo: {message}")
except websockets.exceptions.ConnectionClosed as e:
print(f"Connection closed: {e}")

# Main function to start the server
async def main():
# Set up CLI argument parsing
parser = argparse.ArgumentParser(description="WebSocket Server with optional client-requested compression")
parser.add_argument('--port', type=int, default=8765, help="Port number to listen on")

args = parser.parse_args()

# Define the server with compression support (client-requested)
server = await websockets.serve(
echo,
"0.0.0.0", # Address to bind the server
args.port, # Port number from CLI
compression="deflate" # Enable permessage-deflate compression if the client requests it
)

print(f"WebSocket server started on ws://localhost:{args.port}")
print("Compression will be enabled if the client requests it.")

# Run the server until it's manually stopped
await server.wait_closed()

# Run the server
if __name__ == "__main__":
asyncio.run(main())
50 changes: 50 additions & 0 deletions additions/websocket-server/websocket.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Namespace definition (if the namespace doesn't already exist)
apiVersion: v1
kind: Namespace
metadata:
name: sock-shop

---
# Deployment for the WebSocket server
apiVersion: apps/v1
kind: Deployment
metadata:
name: websocket-server-deployment
namespace: sock-shop
labels:
app: websocket-server
spec:
replicas: 1 # Adjust the number of replicas as needed
selector:
matchLabels:
app: websocket-server
template:
metadata:
labels:
app: websocket-server
spec:
containers:
- name: websocket-server-container
image: kubeshark/mizutest-websocket-server:latest # Replace with your actual image name and version
ports:
- containerPort: 8765 # Port exposed by your WebSocket server inside the container
env:
- name: PORT
value: "8765" # The port the app listens on, passed via environment variable
---
# Service to expose the WebSocket server within the sock-shop namespace
apiVersion: v1
kind: Service
metadata:
name: websocket-server-service
namespace: sock-shop
labels:
app: websocket-server
spec:
selector:
app: websocket-server
ports:
- protocol: TCP
port: 80 # Port the service exposes (external port)
targetPort: 8765 # The port the WebSocket server listens on inside the container
type: ClusterIP # This makes the service accessible only within the cluster
19 changes: 0 additions & 19 deletions deploy/kubernetes/complete-demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2037,22 +2037,3 @@ spec:
targetPort: 50051
selector:
name: mizutest-sctp-client
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: kubeshark-hub-network-policy
namespace: sock-shop
spec:
egress:
- {}
ingress:
- ports:
- port: 50051
protocol: SCTP
podSelector:
matchLabels:
name: mizutest-sctp-server
policyTypes:
- Ingress
- Egress
Binary file removed deploy/kubernetes/kubeshark
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ spec:
- command:
- sh
- -c
- ./run.sh # > /dev/null 2>&1
- ./run.sh true # > /dev/null 2>&1
env:
- name: PYTHONUNBUFFERED
value: '1'
Expand Down
27 changes: 27 additions & 0 deletions deploy/kubernetes/ws-demo-block.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-egress-ws-client
namespace: sock-shop # specify the namespace if different
spec:
podSelector:
matchLabels:
app: mizutest-websocket-client # label of the pod you want to block egress for
policyTypes:
- Egress
egress: [] # Empty egress block means no egress is allowed

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-ingress-ws-server
namespace: sock-shop # specify the namespace if different
spec:
podSelector:
matchLabels:
app: websocket-server # label of the pod you want to block ingress for
policyTypes:
- Ingress
ingress: [] # Empty ingress block means no ingress is allowed
Loading

0 comments on commit 02358cb

Please sign in to comment.