Updated with correct code

This commit is contained in:
jenkins-x-bot 2020-09-12 23:51:12 +08:00
parent 8d6123db47
commit a1db290bd3
12 changed files with 174 additions and 81 deletions

8
app.py
View File

@ -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))

View File

@ -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

View File

@ -1,4 +0,0 @@
from google.appengine.ext import vendor
# Add any libraries installed in the "lib" folder.
vendor.add('venv/lib')

View File

@ -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
View File

@ -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
View File

@ -0,0 +1,4 @@
from flask import Blueprint
routes = Blueprint('routes', __name__)
from .kube_helm_routes import *

View File

@ -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)

View 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
View 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"})

View 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>

View 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>

View File

@ -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;
}) })