Skip to content

Commit

Permalink
Merge pull request #20 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 81a20fb + bd626af commit 80701a9
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 68 deletions.
112 changes: 60 additions & 52 deletions labapp/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +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
from fetch import get_runner_session, cloudapp_fetch, cloudapp_req_headers, cloudapp_res_headers

app = Flask(__name__)
app.config['ce_info'] = None
Expand All @@ -21,6 +21,9 @@
cache = Cache(app)
app.secret_key = "blahblahblah"

session = get_runner_session()
session.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})

class LabException(Exception):
"""lab exception"""

Expand Down Expand Up @@ -206,142 +209,145 @@ def score():
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, 7, 'info', {"foo": True})
data = cloudapp_fetch(session, url, 7, 'info', {"foo": True})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@app.route('/_test2')
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, 7, 'info', {"bar": True})
data = cloudapp_fetch(session, url, 7, 'info', {"bar": True})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")


@app.route('/_lb1')
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, 7, 'env', 'AWS')
data = cloudapp_fetch(session, url, 7, 'env', 'AWS')
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))

except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@app.route('/_lb2')
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, 7, 'env', 'Azure')
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
for _ in range(5):
try:
data = cloudapp_fetch(session, url, 7, 'env', 'Azure')
return jsonify(status='success', data=data)
except ValueError:
pass
raise ValueError("Failed to find Azure Origin Pool")
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@app.route('/_route1')
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, 7, 'env', 'AWS')
azure_data = cloudapp_fetch(s, azure_url, 7, 'env', 'Azure')
aws_data = cloudapp_fetch(session, aws_url, 7, 'env', 'AWS')
azure_data = cloudapp_fetch(session, 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:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@app.route('/_route2')
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, 7, 'env', 'AWS')
s.headers["X-MCN-lab"] = "azure"
azure_data = cloudapp_fetch(s, azure_url, 7, 'env', 'Azure')
session.headers["X-MCN-lab"] = "aws"
aws_data = cloudapp_fetch(session, aws_url, 7, 'env', 'AWS')
session.headers["X-MCN-lab"] = "azure"
azure_data = cloudapp_fetch(session, 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:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@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', {"method": "GET", "path": "/raw"})
r_data = cloudapp_fetch(session, url, 5, 'info', {"method": "GET", "path": "/raw"})
return jsonify(status='success', data=r_data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@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)
r_data = cloudapp_req_headers(session, url, 7, t_headers)
return jsonify(status='success', data=r_data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@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")
Expand All @@ -350,45 +356,47 @@ def manip3():
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)
aws_data = cloudapp_res_headers(session, aws_url, 7, aws_headers)
azure_data = cloudapp_res_headers(session, 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:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@app.route('/_port1')
def port1():
"""Friend 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": "/"})
data = cloudapp_fetch(session, url, 7, 'info', {"method": "GET", "path": "/"})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")

@app.route('/_port2', methods=['POST'])
def port2():
"""Friend test"""
try:
s = requests.Session()
s.headers.update({"User-Agent": "MCN-Lab-Runner/1.0"})
data = request.get_json()
print(data)
eph_ns = data['userInput']
url = f"https://{eph_ns}.{app.config['base_url']}/"
data = cloudapp_fetch(s, url, 7, 'info', {"method": "GET", "path": "/"})
data = cloudapp_fetch(session, url, 7, 'info', {"method": "GET", "path": "/"})
return jsonify(status='success', data=data)
except (LabException, requests.RequestException, ValueError) as e:
except (LabException, ValueError) as e:
return jsonify(status='fail', error=str(e))
except requests.RequestException:
return jsonify(status='fail', error="Connection/Request Error")


if __name__ == '__main__':
Expand Down
26 changes: 24 additions & 2 deletions labapp/app/fetch.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
from requests.structures import CaseInsensitiveDict
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def get_runner_session(
retries=3,
backoff_factor=0.3,
status_forcelist=(500, 502, 504),
session=None
):
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session

def headers_cleaner(headers):
"""
Expand Down Expand Up @@ -39,7 +61,7 @@ def cloudapp_req_headers(session, url, timeout, headers):
for header in headers:
head_value = req_headers.get(header)
if not head_value:
raise ValueError(f"Header {header} not found request headers.")
raise ValueError(f"Header {header} not found request headers")
clean_headers = headers_cleaner(data['request_headers'])
data['request_headers'] = clean_headers
return data
Expand All @@ -55,6 +77,6 @@ def cloudapp_res_headers(session, url, timeout, 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}.")
raise ValueError(f"Header {header} not found response headers from {url}")
header_dict = dict(data)
return header_dict
16 changes: 12 additions & 4 deletions labapp/app/markdown/lb.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<div href="/" class="d-flex align-items-center pb-3 mb-3 link-dark text-decoration-none border-bottom"></div>

Load balancing is the cornerstone of XC's App Connect functionality.
L7 MCN requires discovering services at one site and making those services available at some other site.
That's accomplished by configuring origin pools and load balancers.
L7 MCN requires discovering services at one site and making those services available to another.
XC implements this functionality with <strong>origin pools</strong> and <strong>load balancers</strong>.
More complicated configurations (underlay networking, security services, observability, etc.) are built on these primitives.

<div style="height:25px"></div>
Expand All @@ -21,7 +21,7 @@ Build an origin pool and load balancer based on the exercise requirements.
<ul class="list-group">
<li class="list-group-item">
<img src="/static/origin-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
The URL for the cloud app hosted in AWS is <a href="https://aws-cloud-app.mcn-lab.f5demos.com">https://aws-cloud-app.mcn-lab.f5demos.com</a>
The URL for the cloud app hosted in AWS is <strong>https://aws-cloud-app.mcn-lab.f5demos.com</strong>
</li>
<li class="list-group-item">
<img src="/static/origin-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
Expand Down Expand Up @@ -112,7 +112,7 @@ Create a new origin pool for the Azure cloud app. Reuse your load balancer.
<ul class="list-group">
<li class="list-group-item">
<img src="/static/origin-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
The URL for the cloud app hosted in Azure is <a href="https://azure-cloud-app.mcn-lab.f5demos.com">https://aws-cloud-app.mcn-lab.f5demos.com</a>
The URL for the cloud app hosted in Azure is <strong>https://azure-cloud-app.mcn-lab.f5demos.com</strong>
</li>
<li class="list-group-item">
<img src="/static/origin-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
Expand All @@ -122,6 +122,10 @@ Create a new origin pool for the Azure cloud app. Reuse your load balancer.
<img src="/static/origin-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
The cloud app is TLS only.
</li>
<li class="list-group-item">
<img src="/static/lb-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
Keep the AWS Origin Pool in place.
</li>
</ul>

<div style="height:25px"></div>
Expand All @@ -138,6 +142,10 @@ Host: eph-ns.mcn-lab.f5demos.com
}
```

<div class="alert alert-secondary" role="alert">
<strong>This test will make up to 5 requests.</strong>
</div>

<div class="left-aligned-button-container">
<button id="requestBtn2" class="btn btn-primary">Test Load Balancer</button>
</div>
Expand Down
10 changes: 5 additions & 5 deletions labapp/app/markdown/manipulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,14 @@ document.getElementById('requestBtn2').addEventListener('click', () => {
<ul class="list-group">
<li class="list-group-item">
<img src="/static/lb-icon.png" width="auto" height="50px"> &nbsp; &nbsp;
Insert a response header named <strong>X-MCN-dst-site</strong> to determine which cloud CE processed the request.
Insert a response header named <strong>X-MCN-dest-site</strong> to determine which cloud CE processed the request.
</li>
</ul>

<div style="height:25px"></div>

#### **Test Criteria**

<div class="alert alert-secondary" role="alert">
This test evaluates response headers.
</div>

```http
GET https://eph-ns.mcn-lab.f5demos.com/aws HTTP/1.1
Host: eph-ns.mcn-lab.f5demos.com
Expand All @@ -160,6 +156,10 @@ Host: eph-ns.mcn-lab.f5demos.com
}
```

<div class="alert alert-secondary" role="alert">
<strong>This test evaluates response headers.</strong>
</div>

<div class="left-aligned-button-container">
<button id="requestBtn3" class="btn btn-primary">Test Load Balancer</button>
</div>
Expand Down
Loading

0 comments on commit 80701a9

Please sign in to comment.