Skip to content

Commit

Permalink
Merge pull request #18 from f5devcentral/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
kreynoldsf5 authored May 2, 2024
2 parents 33b79b7 + 38e18de commit 06a0fdc
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 71 deletions.
2 changes: 1 addition & 1 deletion cloudapp/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def echo_html():

@app.route('/foo/', methods=['GET'])
def ex_test():
return jsonify({'info': 'bar'})
return jsonify({"info": { "foo": True}})

return app

Expand Down
121 changes: 82 additions & 39 deletions labapp/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import requests
import markdown
from ce import get_ce_info, get_ce_state
from fetch import cloudapp_fetch, cloudapp_req_headers, cloudapp_res_headers

app = Flask(__name__)
app.config['ce_info'] = None
Expand Down Expand Up @@ -43,33 +44,6 @@ def eph_ns() -> str:
this_eph_ns = request.cookies.get('eph_ns', None)
return this_eph_ns

def cloudapp_fetch(session, url, timeout, prop, value, headers = {}):
"""
Fetch data from URL
Validate prop and value in the JSON response
"""
response = session.get(url, timeout=timeout)
response.raise_for_status()
data = response.json()
if data.get(prop) != value:
raise ValueError(f"Invalid {prop}: expected {value}, got {data.get(prop)}")
if data.get("request_headers"):
clean_headers = headers_cleaner(data['request_headers'])
data['request_headers'] = clean_headers
return data
return data

def headers_cleaner(headers):
"""
Remove headers that contain specific substrings.
"""
unwanted_substrings = ['x-envoy', 'cloudfront', 'x-k8se']
filtered_headers = {
key: value for key, value in headers.items()
if not any(substring in key.lower() for substring in unwanted_substrings)
}
return filtered_headers

@app.errorhandler(404)
@app.errorhandler(500)
def return_err(err):
Expand All @@ -80,6 +54,12 @@ def return_err(err):
}
return render_template("error.html", err_img=img[err.code])

@app.after_request
def cache_control(response):
if request.path.startswith("/static/") and request.path.endswith(".png"):
response.headers['Cache-Control'] = 'public, max-age=3600'
return response

@app.route('/')
def index():
"""index page"""
Expand Down Expand Up @@ -179,7 +159,7 @@ def port():

@app.route('/vnet')
def vnet():
"""reference page"""
"""vnet page"""
ns = eph_ns()
html = render_md("markdown/reference.md")
return render_template('coming-soon.html',
Expand All @@ -190,7 +170,7 @@ def vnet():

@app.route('/netpolicy')
def netp():
"""reference page"""
"""netpolicy page"""
ns = eph_ns()
html = render_md("markdown/reference.md")
return render_template('coming-soon.html',
Expand Down Expand Up @@ -226,8 +206,9 @@ def ex_test():
"""Example test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
url = f"https://foo.{app.config['base_url']}/"
data = cloudapp_fetch(s, url, 5, 'info', 'bar')
data = cloudapp_fetch(s, url, 7, 'info', {"foo": True})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))
Expand All @@ -237,8 +218,9 @@ def ex_test2():
"""Example test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
url = f"https://bar.{app.config['base_url']}/"
data = cloudapp_fetch(s, url, 5, 'info', 'foo')
data = cloudapp_fetch(s, url, 7, 'info', {"bar": True})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))
Expand All @@ -249,11 +231,12 @@ def lb_aws():
"""Azure LB test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
url = f"https://{ns}.{app.config['base_url']}"
data = cloudapp_fetch(s, url, 5, 'env', 'AWS')
data = cloudapp_fetch(s, url, 7, 'env', 'AWS')
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))
Expand All @@ -263,11 +246,12 @@ def lb_azure():
"""Azure LB test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
url = f"https://{ns}.{app.config['base_url']}"
data = cloudapp_fetch(s, url, 5, 'env', 'Azure')
data = cloudapp_fetch(s, url, 7, 'env', 'Azure')
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))
Expand All @@ -277,14 +261,15 @@ def route1():
"""First Route Test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
base_url = app.config['base_url']
aws_url = f"https://{ns}.{base_url}/aws/raw"
azure_url = f"https://{ns}.{base_url}/azure/raw"
aws_data = cloudapp_fetch(s, aws_url, 5, 'env', 'AWS')
azure_data = cloudapp_fetch(s, azure_url, 5, 'env', 'Azure')
aws_data = cloudapp_fetch(s, aws_url, 7, 'env', 'AWS')
azure_data = cloudapp_fetch(s, azure_url, 7, 'env', 'Azure')
data = {
"aws": aws_data,
"azure": azure_data
Expand All @@ -298,38 +283,96 @@ def route2():
"""First Route Test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
base_url = app.config['base_url']
aws_url = f"https://{ns}.{base_url}/"
azure_url = f"https://{ns}.{base_url}/"
s.headers["X-MCN-lab"] = "aws"
aws_data = cloudapp_fetch(s, aws_url, 5, 'env', 'AWS')
aws_data = cloudapp_fetch(s, aws_url, 7, 'env', 'AWS')
s.headers["X-MCN-lab"] = "azure"
azure_data = cloudapp_fetch(s, azure_url, 5, 'env', 'Azure', headers={"X-MCN-lab": "azure"})
azure_data = cloudapp_fetch(s, azure_url, 7, 'env', 'Azure')
data = {
"aws": aws_data,
"azure": azure_data
}
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))

@app.route('/_manip1')
def manip1():
"""First Manip Test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
base_url = app.config['base_url']
url = f"https://{ns}.{base_url}/aws/raw"
r_data = cloudapp_fetch(s, url, 5, 'info', '{"path": "/"}')
r_data = cloudapp_fetch(s, url, 5, 'info', {"method": "GET", "path": "/raw"})
return jsonify(status='success', data=r_data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))

@app.route('/_manip2')
def manip2():
"""Second Manip Test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
base_url = app.config['base_url']
url = f"https://{ns}.{base_url}/"
t_headers = { "x-mcn-namespace": ns, "x-mcn-src-site": app.config["ce_info"]["site_name"]}
r_data = cloudapp_req_headers(s, url, 7, t_headers)
return jsonify(status='success', data=r_data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))

@app.route('/_manip3')
def manip3():
"""Third Manip Test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
base_url = app.config['base_url']
aws_url = f"https://{ns}.{base_url}/aws/"
azure_url = f"https://{ns}.{base_url}/azure/"
aws_headers = { "x-mcn-dest-site": "student-awsnet" }
azure_headers = { "x-mcn-dest-site": "student-azurenet" }
aws_data = cloudapp_res_headers(s, aws_url, 7, aws_headers)
azure_data = cloudapp_res_headers(s, azure_url, 7, azure_headers)
data = {
"aws": aws_data,
"azure": azure_data
}
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))

@app.route('/_port1')
def port1():
"""Azure LB test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
ns = eph_ns()
if not ns:
raise LabException("Ephemeral NS not set")
url = f"https://{ns}.{app.config['base_url']}/"
data = cloudapp_fetch(s, url, 7, 'info', {"method": "GET", "path": "/"})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
return jsonify(status='fail', error=str(e))


if __name__ == '__main__':
Expand Down
60 changes: 60 additions & 0 deletions labapp/app/fetch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from requests.structures import CaseInsensitiveDict

def headers_cleaner(headers):
"""
Remove headers that contain specific substrings.
Use this to make responses look nicer.
"""
unwanted_substrings = ['x-envoy', 'cloudfront', 'x-k8se', 'x-amz', 'z-amzn', 'via', 'x-arr-ssl', 'x-ms-containerapp']
filtered_headers = {
key: value for key, value in headers.items()
if not any(substring in key.lower() for substring in unwanted_substrings)
}
return filtered_headers

def cloudapp_fetch(session, url, timeout, prop, value):
"""
Fetch data from URL
Validate prop and value in the JSON response
"""
response = session.get(url, timeout=timeout)
response.raise_for_status()
data = response.json()
if data.get(prop) != value:
raise ValueError(f'Invalid {prop}: expected {value}, got {data.get(prop)}')
if data.get("request_headers"):
clean_headers = headers_cleaner(data['request_headers'])
data['request_headers'] = clean_headers
return data
return data

def cloudapp_req_headers(session, url, timeout, headers):
"""
Fetch data from URL
"""
response = session.get(url, timeout=timeout)
response.raise_for_status()
data = response.json()
req_headers = CaseInsensitiveDict(data['request_headers'])
for header in headers:
head_value = req_headers.get(header)
if not head_value:
raise ValueError(f"Header {header} not found request headers.")
clean_headers = headers_cleaner(data['request_headers'])
data['request_headers'] = clean_headers
return data

def cloudapp_res_headers(session, url, timeout, headers):
"""
Fetch data from URL
Check for response header
"""
response = session.get(url, timeout=timeout)
response.raise_for_status()
data = response.headers
for header in headers:
head_value = data.get(header)
if not head_value:
raise ValueError(f"Header {header} not found response headers from {url}.")
header_dict = dict(data)
return header_dict
2 changes: 1 addition & 1 deletion labapp/app/markdown/lb.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div href="/" class="d-flex align-items-center pb-3 mb-3 link-dark text-decoration-none">
<img src="/static/load-balancing.png" width="300px" height="auto" alt="intro">
<img src="/static/lb.png" width="300px" height="auto" alt="intro">
</div>

# **Load Balancing**
Expand Down
Loading

0 comments on commit 06a0fdc

Please sign in to comment.