Skip to content

Commit fd3ab2f

Browse files
djmailhotandrewsg
authored andcommitted
Demo webserver for managed instances tutorial (#2077)
* Add compute/managed-instances/demo/webserver.py as tutorial sample code * Update managed-instances demo webserver to run with Python3 * Lint fixes for managed-instances demo webserver * Python3 fixes for managed-instances demo webserver * Update managed-instances demo webserver to use Flask * Add copywrite header * managed instances demo Flask app refactor long lines * managed instances demo app actually uses PORT_NUMBER global * managed instances demo app fix gethostname reference * Add comments to managed instances demo app
1 parent 1a16d10 commit fd3ab2f

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

compute/managed-instances/demo/app.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Copyright 2019, Google, Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
"""
14+
Flask app to be used as an interactive demonstration of autohealing.
15+
16+
Exposes a simple UI showing basic server stats and a toggle button to
17+
simulate a healthy/unhealthy server status for any attached health check.
18+
19+
Attached health checks should query the '/health' path.
20+
"""
21+
22+
from flask import Flask, make_response, render_template
23+
from re import sub
24+
from requests import get
25+
from socket import gethostname
26+
27+
PORT_NUMBER = 80
28+
29+
app = Flask(__name__)
30+
healthy = True
31+
32+
33+
@app.route('/')
34+
def index():
35+
"""Returns the demo UI."""
36+
global healthy
37+
return render_template('index.html',
38+
hostname=gethostname(),
39+
zone=_get_zone(),
40+
template=_get_template(),
41+
healthy=healthy)
42+
43+
44+
@app.route('/health')
45+
def health():
46+
"""Returns the simulated 'healthy'/'unhealthy' status of the server.
47+
48+
Returns:
49+
HTTP status 200 if 'healthy', HTTP status 500 if 'unhealthy'
50+
"""
51+
global healthy
52+
template = render_template('health.html', healthy=healthy)
53+
return make_response(template, 200 if healthy else 500)
54+
55+
56+
@app.route('/makeHealthy')
57+
def make_healthy():
58+
"""Sets the server to simulate a 'healthy' status."""
59+
global healthy
60+
healthy = True
61+
template = render_template('index.html',
62+
hostname=gethostname(),
63+
zone=_get_zone(),
64+
template=_get_template(),
65+
healthy=True)
66+
response = make_response(template, 302)
67+
response.headers['Location'] = '/'
68+
return response
69+
70+
71+
@app.route('/makeUnhealthy')
72+
def make_unhealthy():
73+
"""Sets the server to simulate an 'unhealthy' status."""
74+
global healthy
75+
healthy = False
76+
template = render_template('index.html',
77+
hostname=gethostname(),
78+
zone=_get_zone(),
79+
template=_get_template(),
80+
healthy=False)
81+
response = make_response(template, 302)
82+
response.headers['Location'] = '/'
83+
return response
84+
85+
86+
def _get_zone():
87+
"""Gets the GCE zone of this instance.
88+
89+
Returns:
90+
str: The name of the zone if the zone was successfully determined.
91+
Empty string otherwise.
92+
"""
93+
r = get('http://metadata.google.internal/'
94+
'computeMetadata/v1/instance/zone',
95+
headers={'Metadata-Flavor': 'Google'})
96+
if r.status_code == 200:
97+
return sub(r'.+zones/(.+)', r'\1', r.text)
98+
else:
99+
return ''
100+
101+
102+
def _get_template():
103+
"""Gets the GCE instance template of this instance.
104+
105+
Returns:
106+
str: The name of the template if the template was successfully
107+
determined and this instance was built using an instance template.
108+
Empty string otherwise.
109+
"""
110+
r = get('http://metadata.google.internal/'
111+
'computeMetadata/v1/instance/attributes/instance-template',
112+
headers={'Metadata-Flavor': 'Google'})
113+
if r.status_code == 200:
114+
return sub(r'.+instanceTemplates/(.+)', r'\1', r.text)
115+
else:
116+
return ''
117+
118+
119+
if __name__ == "__main__":
120+
app.run(debug=False, port=PORT_NUMBER)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
flask==1.0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div style="font-family: verdana; font-weight: bold; font-size: 40px">
2+
{% if healthy %}
3+
<span>HTTP/1.0 200 OK</span>
4+
{% else %}
5+
<span>HTTP/1.0 500 Internal Server Error</span>
6+
{% endif %}
7+
</div>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<html>
2+
<head>
3+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">
4+
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>
5+
</head>
6+
<body>
7+
<table class="striped">
8+
<colgroup>
9+
<col width="200">
10+
</colgroup>
11+
<tbody>
12+
<tr>
13+
<td>Hostname:</td>
14+
<td><b>{{ hostname }}</b></td>
15+
</tr>
16+
<tr>
17+
<td>Zone:</td>
18+
<td><b>{{ zone }}</b></td>
19+
</tr>
20+
<tr>
21+
<td>Template:</td>
22+
<td><b>{{ template }}</b></td>
23+
</tr>
24+
<tr>
25+
<td>Health status:</td>
26+
{% if healthy %}
27+
<td><span class="btn green">healthy</span></td>
28+
{% else %}
29+
<td><span class="btn red">unhealthy</span></td>
30+
{% endif %}
31+
</tr>
32+
<tr>
33+
<td>Actions:</td>
34+
<td>
35+
{% if healthy %}
36+
<a class="btn blue" href="/makeUnhealthy">Make unhealthy</a>
37+
{% else %}
38+
<a class="btn blue" href="/makeHealthy">Make healthy</a>
39+
{% endif %}
40+
41+
<a class="btn blue" href="/health">Check health</a>
42+
</td>
43+
</tr>
44+
</tbody>
45+
</table>
46+
</body>
47+
</html>

0 commit comments

Comments
 (0)