New UI implementation (WIP)

This commit is contained in:
Maxim Kulkin 2013-10-16 16:41:58 +04:00
parent 6b892c61c2
commit f1155f53ec
4 changed files with 88 additions and 20 deletions

View File

@ -1,2 +1,2 @@
webui: gunicorn --error-logfile - --log-level info ostack_validator.webui:app
worker: celery worker --app=ostack_validator.celery:app
webui: gunicorn --error-logfile - --log-level info ostack_validator.webui:app --bind 0.0.0.0:8000
worker: celery worker --app=ostack_validator.celery:app

View File

@ -10,16 +10,16 @@
<title>Feed Example - Semantic</title>
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700|Open+Sans:300italic,400,300,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="semantic-ui/packaged/css/semantic.css">
<link rel="stylesheet" type="text/css" href="/static/semantic-ui/packaged/css/semantic.css">
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.address/1.6/jquery.address.js"></script>
<script src="semantic-ui/packaged/javascript/semantic.js"></script>
<script src="lib/angular.min.js"></script>
<script src="lib/moment.min.js"></script>
<script src="/static/semantic-ui/packaged/javascript/semantic.js"></script>
<script src="/static/lib/angular.min.js"></script>
<script src="/static/lib/moment.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script src="js/main.js"></script>
<link rel="stylesheet" type="text/css" href="/static/css/main.css">
<script src="/static/js/main.js"></script>
</head>
<body>

View File

@ -1,16 +1,18 @@
from itertools import groupby
import os.path
from flask import Flask, request, redirect, render_template, json
from flask import Flask, request, redirect, render_template, json, send_file
from flask_bootstrap import Bootstrap
from flask_wtf import Form
from wtforms import StringField, TextAreaField, SubmitField
from wtforms import StringField, TextAreaField, SubmitField, SelectMultipleField
from wtforms.validators import DataRequired
import wtforms_json
from ostack_validator.celery import app as celery, ostack_inspect_task, InspectionRequest
from ostack_validator.common import Issue, MarkedIssue
from ostack_validator.model import Openstack
app = Flask(__name__)
app = Flask(__name__, static_folder='../config-validator-ui-concept', static_url_path='/static')
Bootstrap(app)
app.debug = True
app.config.update(
@ -18,16 +20,57 @@ app.config.update(
)
app.secret_key = 'A0Zr98j/3fooN]LWX/,?RT'
wtforms_json.init()
class ValidationLaunchForm(Form):
nodes = StringField('Nodes', validators=[DataRequired()])
username = StringField(
'Username',
default='root',
validators=[DataRequired()])
private_key = TextAreaField('Private Key', validators=[DataRequired()])
def connect_to_db():
mongo_url = os.environ.get("MONGODB_URI") or "mongodb://localhost/rubick"
client = MongoClient(mongo_url)
return client[mongo_url.split('/')[-1]]
launch = SubmitField('Launch validation')
def get_db():
db = connect_to_db()
return db
class Cluster(object):
@classmethod
def from_doc(klass, doc):
return Cluster(doc['name'], doc['seed_nodes'], doc['nodes'], doc['private_key'])
def __init__(self, id, name, seed_nodes, private_key, nodes):
super(Cluster, self).__init__()
self.id = id
self.name = name
self.seed_nodes = seed_nodes
self.private_key = private_key
self.nodes = nodes
class RuleGroup:
VALIDITY='validity'
HA='high-availability'
BEST_PRACTICES='best-practices'
all = [VALIDITY, HA, BEST_PRACTICES]
class Rule(object):
@classmethod
def from_doc(klass, doc):
return Rule(doc['id'], doc['group'], doc['name'], doc['text'])
def __init__(self, id, group, name, text):
super(Rule, self).__init__()
self.id = id
self.group = group
self.name = name
self.text = text
class ClusterForm(Form):
name = StringField('Name', validators=[DataRequired()])
nodes = StringField('Nodes', validators=[DataRequired()])
private_key = TextAreaField('Private Key', validators=[DataRequired()])
class ValidateClusterForm(Form):
cluster_id = StringField('Cluster', validators=[DataRequired()])
rules = SelectMultipleField('Rules')
@app.template_filter()
@ -42,7 +85,31 @@ def to_label(s):
@app.route('/')
def index():
return redirect('/validation')
return send_file(os.path.join(app.static_folder, 'index.html'))
@app.route('/clusters')
def get_clusters():
db = get_db()
return json.dumps([Cluster.from_doc(doc) for doc in db['clusters'].find()])
@app.route('/clusters', methods=['POST'])
def add_cluster():
form = ClusterForm.from_json(json.loads(request.data))
if form.validate():
cluster = Cluster()
form.populate_obj(cluster)
get_db()['clusters'].save(cluster)
return '', 201
else:
return json.dumps(dict(errors=form.errors)), 422
@app.route('/rules/<group>')
def get_rules(group):
if not group in RuleGroup.all:
return 'Unknown rule group "%s"' % group, 404
rules = [Rule.from_doc(doc) for doc in db['rules'].find({'group': group})]
return json.dumps(rules)
@app.route('/validation', methods=['GET', 'POST'])

View File

@ -2,6 +2,7 @@ spur==0.3.5
Flask==0.10.1
Flask-Bootstrap>=3.0.0
Flask-WTF==0.9.2
WTForms-JSON>=0.2.2
gunicorn==18.0
celery-with-redis>=3.0
# Jinja2==2.7.1