Updated with correct code
This commit is contained in:
parent
8d6123db47
commit
a1db290bd3
8
app.py
8
app.py
@ -1,13 +1,7 @@
|
|||||||
# encoding=utf-8
|
# encoding=utf-8
|
||||||
import random
|
|
||||||
import string
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_bootstrap import Bootstrap
|
from flask_bootstrap import Bootstrap
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = "4pFwRNNXs+xQSOEaHrq4iSBwl+mq1UTdRuxqhM+RQpo="
|
app.secret_key = "4pFwRNNXs+xQSOEaHrq4iSBwl+mq1UTdRuxqhM+RQpo="
|
||||||
Bootstrap(app)
|
Bootstrap(app)
|
||||||
|
|
||||||
def randomUrlSuffix(stringLength=6):
|
|
||||||
lettersAndDigits = string.ascii_letters + string.digits
|
|
||||||
return ''.join(random.choice(lettersAndDigits) for i in range(stringLength))
|
|
||||||
35
app.yaml
35
app.yaml
@ -1,35 +0,0 @@
|
|||||||
runtime: python27
|
|
||||||
api_version: 1
|
|
||||||
threadsafe: true
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- url: /static
|
|
||||||
static_dir: static
|
|
||||||
- url: /.*
|
|
||||||
script: main.app
|
|
||||||
secure: always
|
|
||||||
|
|
||||||
|
|
||||||
libraries:
|
|
||||||
- name: ssl
|
|
||||||
version: "latest"
|
|
||||||
- name: MySQLdb
|
|
||||||
version: "1.2.5"
|
|
||||||
- name: flask
|
|
||||||
version: latest
|
|
||||||
|
|
||||||
|
|
||||||
env_variables:
|
|
||||||
CLOUDSQL_CONNECTION_NAME: hk-hockey:asia-east2:hk-hockey-sql
|
|
||||||
CLOUDSQL_USER: root
|
|
||||||
CLOUDSQL_WRITE_USER: hockeyWrite
|
|
||||||
CLOUDSQL_READ_USER: hockeyRead
|
|
||||||
CLOUDSQL_PASSWORD: P8P1YopMlwg8TxhE
|
|
||||||
CLOUDSQL_WRITE_PASSWORD: 1URYcxXXlQ6xOWgj
|
|
||||||
CLOUDSQL_READ_PASSWORD: o4GWrbbkBKy3oR6u
|
|
||||||
CLOUDSQL_DATABASE: 2019_hockeyResults
|
|
||||||
CLOUDSQL_DATABASE_STATIC: hockeyResults
|
|
||||||
CLOUDSQL_CHARSET: utf8
|
|
||||||
BASIC_AUTH_USERNAME: admin
|
|
||||||
BASIC_AUTH_PASSWORD: hATnNYriYN5ZrHvXcaImtXJ8SGMonNym
|
|
||||||
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
from google.appengine.ext import vendor
|
|
||||||
|
|
||||||
# Add any libraries installed in the "lib" folder.
|
|
||||||
vendor.add('venv/lib')
|
|
||||||
8
forms.py
8
forms.py
@ -3,15 +3,13 @@ from app import app
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import BooleanField, StringField, PasswordField, TextField, IntegerField, TextAreaField, SubmitField, RadioField, SelectField
|
from wtforms import BooleanField, StringField, PasswordField, TextField, IntegerField, TextAreaField, SubmitField, RadioField, SelectField
|
||||||
from wtforms.fields.html5 import DateField
|
from wtforms.fields.html5 import DateField
|
||||||
from wtforms_components import read_only
|
|
||||||
from wtforms import validators, ValidationError
|
from wtforms import validators, ValidationError
|
||||||
from wtforms.validators import InputRequired, Email, Length
|
from wtforms.validators import InputRequired, Email, Length
|
||||||
from readSettings import mySettings
|
|
||||||
from flask_bootstrap import Bootstrap
|
from flask_bootstrap import Bootstrap
|
||||||
|
|
||||||
|
|
||||||
class deploySelectForm(FlaskForm):
|
class deploySelectForm(FlaskForm):
|
||||||
namespace = SelectField('namespace', validators=[InputRequired(), Length(min=4, max=15)])
|
namespace = SelectField('namespace', choices=[], coerce=str)
|
||||||
deployment = SelectField('password', validators=[InputRequired(), Length(min=4, max=80)])
|
chart = SelectField('chart', choices=[])
|
||||||
version = SelectField('remember me')
|
version = SelectField('remember me')
|
||||||
|
submitButton = SubmitField("Submit")
|
||||||
36
main.py
36
main.py
@ -13,7 +13,8 @@ from routes import *
|
|||||||
from logging import error, info
|
from logging import error, info
|
||||||
from subprocess import STDOUT, CalledProcessError, check_output
|
from subprocess import STDOUT, CalledProcessError, check_output
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
import json
|
|
||||||
|
app.register_blueprint(routes)
|
||||||
|
|
||||||
def get_namespaces():
|
def get_namespaces():
|
||||||
command = "/usr/local/bin/kubectl get ns -ojson"
|
command = "/usr/local/bin/kubectl get ns -ojson"
|
||||||
@ -39,16 +40,31 @@ def get_deployments(namespace):
|
|||||||
data = json.loads(output)
|
data = json.loads(output)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@app.route('/', methods=['GET', 'POST'])
|
def get_charts(namespace):
|
||||||
def namespacesForm():
|
command = "/usr/bin/helm -n " + namespace + " list -ojson"
|
||||||
form = deploySelectForm()
|
info(f"Running command: {command}")
|
||||||
namespaces = get_namespaces()
|
try:
|
||||||
print('Here we are')
|
output = check_output(command.split(" "), stderr=STDOUT).decode("utf-8")
|
||||||
if form.validate_on_submit():
|
except CalledProcessError as err:
|
||||||
return redirect(url_for('/'))
|
error(err.output.decode("utf-8"))
|
||||||
# return '<h1>Something went wrong there</h1>'
|
raise err
|
||||||
|
info(f"Output from command:\n{output}")
|
||||||
|
data = json.loads(output)
|
||||||
|
return data
|
||||||
|
|
||||||
return render_template('index.html', namespaces=namespaces, form=form)
|
def get_chartdata(namespace, chart):
|
||||||
|
command = "/usr//bin/helm -n " + namespace + " history " + chart + " -ojson"
|
||||||
|
info(f"Running command: {command}")
|
||||||
|
print(f"Running command: {command}")
|
||||||
|
try:
|
||||||
|
output = check_output(command.split(" "), stderr=STDOUT).decode("utf-8")
|
||||||
|
except CalledProcessError as err:
|
||||||
|
error(err.output.decode("utf-8"))
|
||||||
|
raise err
|
||||||
|
info(f"Output from command:\n{output}")
|
||||||
|
data = json.loads(output)
|
||||||
|
print(data)
|
||||||
|
return data
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(host='0.0.0.0', port=3000, debug=True)
|
app.run(host='0.0.0.0', port=3000, debug=True)
|
||||||
|
|||||||
4
routes/__init__.py
Normal file
4
routes/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from flask import Blueprint
|
||||||
|
routes = Blueprint('routes', __name__)
|
||||||
|
|
||||||
|
from .kube_helm_routes import *
|
||||||
@ -1,17 +0,0 @@
|
|||||||
from flask import render_template, request
|
|
||||||
from forms import searchForm, playerRecordsForm, teamRecordsForm, clubPlayingRecordsForm
|
|
||||||
from . import routes
|
|
||||||
from tables import Results, playerResults, teamResults, clubPlayingRecord
|
|
||||||
import datetime
|
|
||||||
from datetime import date
|
|
||||||
|
|
||||||
@routes.route('/')
|
|
||||||
def deploySelect():
|
|
||||||
namespaces =
|
|
||||||
sql2 = "SELECT nextClub, oppoLogo FROM hkfcDAdminSettings"
|
|
||||||
clubs = sql_read_static(sql)
|
|
||||||
settings = sql_read_static(sql2)
|
|
||||||
form = teamRecordsForm()
|
|
||||||
form.clubName.choices = [(name['hockeyClub'], name['hockeyClub']) for name in clubs]
|
|
||||||
clubLogo = settings[0]['oppoLogo']
|
|
||||||
return render_template('_teamRecords.html', data=clubs, selectedClubLogo=clubLogo, form=form)
|
|
||||||
36
routes/kube_helm_routes.py
Normal file
36
routes/kube_helm_routes.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from flask import render_template, request, jsonify
|
||||||
|
from forms import deploySelectForm
|
||||||
|
from main import get_namespaces, get_charts, get_chartdata
|
||||||
|
from . import routes
|
||||||
|
from tables import chartVersionTable
|
||||||
|
import json
|
||||||
|
|
||||||
|
@routes.route('/', methods=['GET', 'POST'])
|
||||||
|
def index():
|
||||||
|
namespaces = get_namespaces()
|
||||||
|
print(namespaces)
|
||||||
|
form = deploySelectForm()
|
||||||
|
form.namespace.choices = [(name['metadata']['name'], name['metadata']['name']) for name in namespaces['items']]
|
||||||
|
return render_template('nameChartSelect.html', namespaces=namespaces, form=form)
|
||||||
|
|
||||||
|
@routes.route('/chartSelect', methods=['POST'])
|
||||||
|
def chartVersions():
|
||||||
|
namespace = request.form['namespace']
|
||||||
|
chart = request.form['chart']
|
||||||
|
chartVersions = get_chartdata(namespace, chart)
|
||||||
|
print(chartVersions)
|
||||||
|
table = chartVersionTable(chartVersions)
|
||||||
|
table.border = True
|
||||||
|
table.classes = ['table-striped', 'table-condensed', 'table-hover']
|
||||||
|
return render_template('chartRevisionList.html', table=table, namespace=namespace, chart=chart)
|
||||||
|
|
||||||
|
|
||||||
|
@routes.route('/nsLookup/<namespace>')
|
||||||
|
def namespaceLookup(namespace):
|
||||||
|
charts = get_charts(namespace)
|
||||||
|
return jsonify(charts)
|
||||||
|
|
||||||
|
@routes.route('/deployChartRevision/<revision>')
|
||||||
|
def deployChartRevision(revision):
|
||||||
|
charts = get_charts(namespace)
|
||||||
|
return jsonify(charts)
|
||||||
10
tables.py
Normal file
10
tables.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from flask_table import Table, Col, LinkCol, ButtonCol
|
||||||
|
|
||||||
|
class chartVersionTable(Table):
|
||||||
|
revision = Col('Chart Revision')
|
||||||
|
updated = Col('Updated')
|
||||||
|
status = Col('Status')
|
||||||
|
chart = Col('Chart Version')
|
||||||
|
app_version = Col('Application Version')
|
||||||
|
description = Col('Description')
|
||||||
|
deploy = ButtonCol('Deploy', 'routes.deployChartRevision', url_kwargs=dict(revision='revision'), button_attrs={"type" : "submit", "class" : "btn btn-danger"})
|
||||||
26
templates/chartRevisionList.html
Normal file
26
templates/chartRevisionList.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<doctype html>
|
||||||
|
<head>
|
||||||
|
<title>List of deployed chart revisions</title>
|
||||||
|
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||||
|
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<script src="/static/js/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
{% with messages = get_flashed_messages() %}
|
||||||
|
{% if messages %}
|
||||||
|
<ul class=flashes>
|
||||||
|
{% for message in messages %}
|
||||||
|
<li>{{ message }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
</p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
{{ table }}
|
||||||
|
</table>
|
||||||
|
<a class="btn btn-primary" href="/" role="button">Home</a>
|
||||||
|
</body>
|
||||||
65
templates/nameChartSelect.html
Normal file
65
templates/nameChartSelect.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Select Namespace and Chart *TESTING*</title>
|
||||||
|
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||||
|
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<script src="/static/js/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<h2>Select both a namespace and chart</h2>
|
||||||
|
<body onload="myFunction()">
|
||||||
|
<dl>
|
||||||
|
<p>
|
||||||
|
{{ form.csrf_token }}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<form class="col-sm-6" method="post" action="/chartSelect">
|
||||||
|
<div class = "row">
|
||||||
|
<div class = "col-sm-6">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon" id="basic-addon1">Namespace:</span>
|
||||||
|
{{ form.namespace(class_="form-control") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class = "col-sm-6">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon" id="basic-addon2">Chart:</span>
|
||||||
|
{{ form.chart(class_="form-control") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
{{ form.submitButton(class_="btn btn-success") }}
|
||||||
|
<a class="btn btn-danger" href="/" role="button">Cancel</a>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var namespaceSelect = document.getElementById("namespace");
|
||||||
|
var chartSelect = document.getElementById("chart");
|
||||||
|
|
||||||
|
namespaceSelect.onchange = function() {myFunction()};
|
||||||
|
|
||||||
|
function myFunction() {
|
||||||
|
|
||||||
|
namespace = namespaceSelect.value;
|
||||||
|
|
||||||
|
fetch('/nsLookup/' + namespace).then(function(response) {
|
||||||
|
response.json().then(function(data) {
|
||||||
|
var optionHTML = '';
|
||||||
|
for (var chart of data) {
|
||||||
|
optionHTML += '<option value="' + chart.name + '">' + chart.name + '</option>';
|
||||||
|
}
|
||||||
|
chartSelect.innerHTML = optionHTML;
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
{{ form.namespace(class_="form-control") }}
|
{{ form.namespace(class_="form-control") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class = "col-sm-4">
|
<div class = "col-sm-6">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-addon" id="basic-addon2">Deployment:</span>
|
<span class="input-group-addon" id="basic-addon2">Deployment:</span>
|
||||||
{{ form.deployment(class_="form-control") }}
|
{{ form.deployment(class_="form-control") }}
|
||||||
@ -52,8 +52,8 @@
|
|||||||
fetch('/nsLookup/' + namespace).then(function(response) {
|
fetch('/nsLookup/' + namespace).then(function(response) {
|
||||||
response.json().then(function(data) {
|
response.json().then(function(data) {
|
||||||
var optionHTML = '';
|
var optionHTML = '';
|
||||||
for (var deployment of data) {
|
for (var deployment of data.items) {
|
||||||
optionHTML += '<option value="' + deployment.deployment + '">' + deployment.deployment + '</option>';
|
optionHTML += '<option value="' + deployment.metadata.name + '">' + deployment.metadata.name + '</option>';
|
||||||
}
|
}
|
||||||
deploymentSelect.innerHTML = optionHTML;
|
deploymentSelect.innerHTML = optionHTML;
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user