Provider Selection

Let user to chose which provider to work on.
This commit is contained in:
root 2016-09-20 01:22:24 +03:00
parent 858b094f32
commit 86933fbe9a
12 changed files with 291 additions and 163 deletions

View File

@ -21,7 +21,7 @@ class DevelopmentConfig(Config):
MAIL_USERNAME = os.environ.get('MAIL_USERNAME') MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD') MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \ SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
('mysql://root:Polo1043@localhost/dashDev') ('mysql+pymysql://root:Polo1043@localhost/dashDev')
SQLALCHEMY_TRACK_MODIFICATIONS = True SQLALCHEMY_TRACK_MODIFICATIONS = True
WTF_CSRF_ENABLED = True WTF_CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess' SECRET_KEY = 'you-will-never-guess'

View File

@ -41,7 +41,15 @@ def create_app(config_name):
login_manager.init_app(dash) login_manager.init_app(dash)
Principal.init_app(dash) Principal.init_app(dash)
toolbar.init_app(dash) toolbar.init_app(dash)
@dash.context_processor
def my_utility_processor():
from .models import Provider
def all_providers():
""" returns the all providers """
return Provider.query.all()
return dict(all_providers=all_providers)
# attach routes and custom error pages here # attach routes and custom error pages here

View File

@ -4,7 +4,7 @@ from flask_login import login_user, logout_user, login_required, \
current_user current_user
from . import auth from . import auth
from .. import db from .. import db
from ..models import User, Role from ..models import User, Role, Provider
from ..email import send_email from ..email import send_email
from .forms import LoginForm, RegistrationForm, PasswordResetRequestForm, \ from .forms import LoginForm, RegistrationForm, PasswordResetRequestForm, \
PasswordResetForm PasswordResetForm

View File

@ -1,8 +1,10 @@
from flask_wtf import Form from flask_wtf import Form
from wtforms import StringField, SubmitField from flask import flash
from wtforms.validators import Required from wtforms import StringField, PasswordField, BooleanField, SubmitField, ValidationError
from wtforms.validators import Required, Length, Email, Regexp, EqualTo
from ..models import User, Provider, Role
class NameForm(Form): class SelectProvider(Form):
name = StringField('What is your name?', validators=[Required()]) provider = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit') submit = SubmitField('Submit')

View File

@ -1,28 +1,43 @@
import dateutil.parser import dateutil.parser
from flask import render_template, session, redirect, url_for, current_app from flask import render_template, redirect, request, url_for, flash, \
current_app, session
from flask_login import login_required from flask_login import login_user, logout_user, login_required, \
current_user
from flask_principal import Identity, AnonymousIdentity, \
identity_changed
from .. import db from .. import db
from ..models import User from ..models import User, Provider, Role
from ..email import send_email from ..email import send_email
from . import main from . import main
from .forms import NameForm from ..decorators import requires_roles
from .forms import SelectProvider
def redirect_url():
return request.args.get('next') or \
request.referrer or \
url_for('main.index')
@main.route('/', methods=['GET', 'POST']) @main.route('/', methods=['GET', 'POST'])
@login_required @login_required
@requires_roles("user","reseller","admin")
def index(): def index():
return render_template('index.html') return render_template('index.html')
@main.route('/lockscreen')
def lockscreen():
current_user = User()
return render_template('lockscreen.html', current_user=current_user)
@main.route('/reseller') @main.route('/reseller')
@login_required @login_required
@requires_roles("user","reseller","admin")
def for_resellers_only(): def for_resellers_only():
return "For resellers only! We mean it..." return "For resellers only! We mean it..."
@main.route('/select-provider/<int:id>')
@login_required
@requires_roles("user","reseller","admin")
def select_provider(id):
provider = Provider.query.filter_by(id=id).first()
if provider:
session['selected_provider'] = id
return redirect(redirect_url())

View File

@ -37,6 +37,7 @@ class User(UserMixin, db.Model):
provider_password = db.Column(db.Text(255)) provider_password = db.Column(db.Text(255))
confirmed = db.Column(db.Boolean, default=False) confirmed = db.Column(db.Boolean, default=False)
suspended = db.Column(db.Boolean, default=False) suspended = db.Column(db.Boolean, default=False)
selected_provider = None
@property @property
def password(self): def password(self):
@ -107,7 +108,7 @@ class User(UserMixin, db.Model):
return True return True
def __repr__(self): def __repr__(self):
return '<User %r>' % self.username return '<User %r>' % self.username, '<User %r>' % self.selected_provider
class Provider(db.Model): class Provider(db.Model):
__tablename__ = 'providers' __tablename__ = 'providers'

View File

@ -1,13 +1,13 @@
from flask_wtf import Form from flask_wtf import Form
from flask import flash from flask import flash
from wtforms import StringField, PasswordField, BooleanField, SubmitField, \ from wtforms import StringField, PasswordField, BooleanField, SubmitField, \
ValidationError, SelectField ValidationError, SelectField
from wtforms.validators import Required, Length, Email, Regexp, EqualTo, \ from wtforms.validators import Required, Length, Email, Regexp, EqualTo, \
IPAddress IPAddress
from ..models import User, Role, Provider
from flask_login import login_user, logout_user, login_required, \ from flask_login import login_user, logout_user, login_required, \
current_user current_user
from ..models import User, Role, Provider
from keystoneauth1 import identity from keystoneauth1 import identity
from keystoneauth1 import session from keystoneauth1 import session
@ -15,6 +15,29 @@ from neutronclient.v2_0 import client
from novaclient import client as client_nova from novaclient import client as client_nova
class AssignFloatingIP(Form): class AssignFloatingIP(Form):
server = SelectField('Server', choices=int)
def __init__(self, floatingip, *args, **kwargs):
user = User.query.get_or_404(current_user.id)
provider = Provider.query.get_or_404("1")
auth = identity.Password(auth_url=provider.url,
username=user.username,
password=user.provider_password,
project_name=user.username,
project_domain_name='Default',
user_domain_name='Default')
sess = session.Session(auth=auth)
nova = client_nova.Client('2', session=sess)
servers = nova.servers.list()
super(AssignFloatingIP, self).__init__(*args, **kwargs)
self.server.choices = [(server.id, server.name)
for server in servers]
self.floatingip = floatingip
class UnAssignFloatingIP(Form):
floatingip = StringField('Floating IP', validators=[Required(), Length(1, 128), floatingip = StringField('Floating IP', validators=[Required(), Length(1, 128),
IPAddress()]) IPAddress()])
server = SelectField('Server', choices = []) server = StringField('Server')
submit = SubmitField()

View File

@ -1,122 +1,141 @@
import datetime, requests, json, string, random, pprint import datetime, requests, json, string, random, pprint
from keystoneauth1 import identity from keystoneauth1 import identity
from keystoneauth1 import session from keystoneauth1 import session
from neutronclient.v2_0 import client from neutronclient.v2_0 import client
from novaclient import client as client_nova from novaclient import client as client_nova
from flask import render_template, redirect, request, url_for, flash from flask import render_template, redirect, request, url_for, flash
from flask_login import login_user, logout_user, login_required, \ from flask_login import login_user, logout_user, login_required, \
current_user current_user
from flask_principal import Identity, AnonymousIdentity, \ from flask_principal import Identity, AnonymousIdentity, \
identity_changed identity_changed
from .forms import AssignFloatingIP from .forms import AssignFloatingIP, UnAssignFloatingIP
from . import network from . import network
from .. import db from .. import db
from ..models import User, Role, Provider from ..models import User, Role, Provider
from ..email import send_email from ..email import send_email
from ..decorators import requires_roles from ..decorators import requires_roles
def print_values(val, type):
if type == 'ports': @network.route('/', methods=['GET', 'POST'])
val_list = val['ports'] @login_required
if type == 'networks': @requires_roles("user","admin")
val_list = val['networks'] def index():
if type == 'routers': return render_template('network/index.html')
val_list = val['routers']
for p in val_list: @network.route('/list-ips', methods=['GET', 'POST'])
for k, v in p.items(): @login_required
print("%s : %s" % (k, v)) @requires_roles("user","admin")
print('\n') def list_ips():
user = User.query.get_or_404(current_user.id)
provider = Provider.query.get_or_404("1")
@network.route('/', methods=['GET', 'POST']) auth = identity.Password(auth_url=provider.url,
@login_required username=user.username,
@requires_roles("user","admin") password=user.provider_password,
def index(): project_name=user.username,
return render_template('network/index.html') project_domain_name='Default',
user_domain_name='Default')
@network.route('/list-ips', methods=['GET', 'POST']) sess = session.Session(auth=auth)
@login_required neutron = client.Client(session=sess)
@requires_roles("user","admin") nova = client_nova.Client('2', session=sess)
def list_ips(): networks = neutron.list_networks()
user = User.query.get_or_404(current_user.id) subnets = neutron.list_subnets()
provider = Provider.query.get_or_404("1") routers = neutron.list_routers()
auth = identity.Password(auth_url=provider.url, floatingips = neutron.list_floatingips()
username=user.username, ports = neutron.list_ports()
password=user.provider_password, return render_template('network/list_ips.html',
project_name=user.username, title="List Networks",
project_domain_name='Default', block_description = "manage all of your networks",
user_domain_name='Default') user=user, provider=provider,neutron=neutron,nova=nova,
sess = session.Session(auth=auth) networks=networks,subnets=subnets,routers=routers,
neutron = client.Client(session=sess) floatingips=floatingips, ports=ports,
nova = client_nova.Client('2', session=sess) sess=sess)
networks = neutron.list_networks()
subnets = neutron.list_subnets() @network.route('/assign-floatingip/<id>', methods=['GET', 'POST'])
routers = neutron.list_routers() @login_required
floatingips = neutron.list_floatingips() @requires_roles("user","admin")
ports = neutron.list_ports() def assign_floatingip(id):
return render_template('network/list_ips.html', user = User.query.get_or_404(current_user.id)
title="List Networks", provider = Provider.query.get_or_404("1")
block_description = "manage all of your networks", auth = identity.Password(auth_url=provider.url,
user=user, provider=provider,neutron=neutron,nova=nova, username=user.username,
networks=networks,subnets=subnets,routers=routers, password=user.provider_password,
floatingips=floatingips, ports=ports, project_name=user.username,
sess=sess) project_domain_name='Default',
user_domain_name='Default')
@network.route('/assign-floatingip/<id>', methods=['GET', 'POST']) sess = session.Session(auth=auth)
@login_required neutron = client.Client(session=sess)
@requires_roles("user","admin") nova = client_nova.Client('2', session=sess)
def assign_floatingip(id): servers = nova.servers.list()
user = User.query.get_or_404(current_user.id) networks = neutron.list_networks()
provider = Provider.query.get_or_404("1") subnets = neutron.list_subnets()
form = AssignFloatingIP() routers = neutron.list_routers()
auth = identity.Password(auth_url=provider.url, floatingip = neutron.list_floatingips(id=id)
username=user.username, ports = neutron.list_ports()
password=user.provider_password, form = AssignFloatingIP(floatingip=floatingip)
project_name=user.username, if form.validate_on_submit():
project_domain_name='Default', server = form.server.data
user_domain_name='Default') server_assign = nova.servers.get(server)
sess = session.Session(auth=auth) floatingip_assign = floatingip['floatingips'][0]['floating_ip_address']
neutron = client.Client(session=sess) server_assign.add_floating_ip(floatingip_assign)
nova = client_nova.Client('2', session=sess) flash("Floating IP Assigned")
servers = nova.servers.list() return redirect(url_for('.assign_floatingip', id=id))
networks = neutron.list_networks() return render_template('network/assign_floatingip.html',
subnets = neutron.list_subnets() title="Assign Floating IP",
routers = neutron.list_routers() block_description = "assign floating ip to server",
floatingip = neutron.list_floatingips(id=id) form=form,
ports = neutron.list_ports() user=user, provider=provider,neutron=neutron,nova=nova,
return render_template('network/assign_floatingip.html', networks=networks,subnets=subnets,routers=routers,
title="Assign Floating IP", floatingip=floatingip, ports=ports,
block_description = "assign floating ip to server", servers=servers,id=id,
user=user, provider=provider,neutron=neutron,nova=nova, sess=sess)
networks=networks,subnets=subnets,routers=routers,
floatingip=floatingip, ports=ports,form=form, @network.route('/unassign-floatingip/<id>/<server_id>', methods=['GET', 'POST'])
servers=servers, @login_required
sess=sess) @requires_roles("user","admin")
def unassign_floatingip(id,server_id):
@network.route('/edit-subnet/<id>', methods=['GET', 'POST']) user = User.query.get_or_404(current_user.id)
@login_required provider = Provider.query.get_or_404("1")
@requires_roles("admin") auth = identity.Password(auth_url=provider.url,
def edit_subnet(id): username=user.username,
user = User.query.get_or_404(current_user.id) password=user.provider_password,
provider = Provider.query.get_or_404("1") project_name=user.username,
auth = identity.Password(auth_url=provider.url, project_domain_name='Default',
username=user.username, user_domain_name='Default')
password=user.provider_password, sess = session.Session(auth=auth)
project_name=user.username, neutron = client.Client(session=sess)
project_domain_name='Default', nova = client_nova.Client('2', session=sess)
user_domain_name='Default') floatingip = neutron.list_floatingips(id=id)
sess = session.Session(auth=auth) server = server_id
neutron = client.Client(session=sess) server_assign = nova.servers.get(server)
nova = client_nova.Client('2', session=sess) floatingip_assign = floatingip['floatingips'][0]['floating_ip_address']
subnet = neutron.list_subnets(id=id) server_assign.remove_floating_ip(floatingip_assign)
ports = neutron.list_ports(subnet_id=id) flash("Floating IP Unassigned")
return render_template('network/edit_subnet.html', return redirect(url_for('network.assign_floatingip', id=id))
title="Edit Subnet",
block_description = "edit and look subnet details", @network.route('/edit-subnet/<id>', methods=['GET', 'POST'])
subnet=subnet,neutron=neutron,ports=ports,nova=nova, @login_required
@requires_roles("admin")
def edit_subnet(id):
user = User.query.get_or_404(current_user.id)
provider = Provider.query.get_or_404("1")
auth = identity.Password(auth_url=provider.url,
username=user.username,
password=user.provider_password,
project_name=user.username,
project_domain_name='Default',
user_domain_name='Default')
sess = session.Session(auth=auth)
neutron = client.Client(session=sess)
nova = client_nova.Client('2', session=sess)
subnet = neutron.list_subnets(id=id)
ports = neutron.list_ports(subnet_id=id)
return render_template('network/edit_subnet.html',
title="Edit Subnet",
block_description = "edit and look subnet details",
subnet=subnet,neutron=neutron,ports=ports,nova=nova,
sess=sess) sess=sess)

View File

@ -7,6 +7,7 @@ from novaclient import client
from flask import render_template, redirect, request, url_for, flash from flask import render_template, redirect, request, url_for, flash
from flask_login import login_user, logout_user, login_required, \ from flask_login import login_user, logout_user, login_required, \
current_user current_user
from flask_login import session as flask_session
from flask_principal import Identity, AnonymousIdentity, \ from flask_principal import Identity, AnonymousIdentity, \
identity_changed identity_changed
@ -27,7 +28,7 @@ def index():
@requires_roles("user","admin") @requires_roles("user","admin")
def list_servers(): def list_servers():
user = User.query.get_or_404(current_user.id) user = User.query.get_or_404(current_user.id)
provider = Provider.query.get_or_404("1") provider = Provider.query.get_or_404(flask_session['selected_provider'])
loader = loading.get_plugin_loader('password') loader = loading.get_plugin_loader('password')
auth = loader.load_from_options(auth_url=provider.url, auth = loader.load_from_options(auth_url=provider.url,
username=user.username, username=user.username,

View File

@ -195,6 +195,31 @@
</li> </li>
</ul> </ul>
</li> </li>
<!-- Provider Selection Menu -->
<li class="dropdown notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true">
<i class="fa fa-warning"></i>
<span >Select Provider</span>
</a>
<ul class="dropdown-menu">
<li class="header">2 Providers </li>
<li>
<div class="slimScrollDiv" style="position: relative; overflow: hidden; width: auto;"><ul class="menu" style="overflow: hidden; width: 100%;">
{% for provider in all_providers() %}
<li>
<a href="{{ url_for('main.select_provider', id=provider.id) }}">
<i class="ion ion-ios7-people info"></i> {{ provider.name }}
</a>
</li>
{% endfor %}
</ul><div class="slimScrollBar" style="width: 3px; position: absolute; top: 0px; opacity: 0.4; display: none; border-radius: 7px; z-index: 99; right: 1px; height: 195.122px; background: rgb(0, 0, 0);"></div><div class="slimScrollRail" style="width: 3px; height: 100%; position: absolute; top: 0px; display: none; border-radius: 7px; opacity: 0.2; z-index: 90; right: 1px; background: rgb(51, 51, 51);"></div></div>
</li>
<li class="footer"><a href="#">View all providers</a></li>
</ul>
</li>
<!-- User Account: style can be found in dropdown.less --> <!-- User Account: style can be found in dropdown.less -->
<li class="dropdown user user-menu"> <li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
@ -206,7 +231,8 @@
<li class="user-header bg-light-blue"> <li class="user-header bg-light-blue">
<img src="{{ current_user.avatar }}" class="img-circle" alt="User Image" /> <img src="{{ current_user.avatar }}" class="img-circle" alt="User Image" />
<p> <p>
{{ current_user.full_name }} - role : {{ current_user.role.name }} User Name: {{ current_user.full_name }} - Role : {{ current_user.role.name }} <br />
Provider : {{ session['selected_provider'] }} <br />
<small>Member since {{ current_user.created_at.strftime("%b. %Y") }}</small> <small>Member since {{ current_user.created_at.strftime("%b. %Y") }}</small>
</p> </p>
</li> </li>

View File

@ -26,24 +26,30 @@
{%- endblock content_header %} {%- endblock content_header %}
{% block content -%} {% block content -%}
<script type = "text/javascript" language = "javascript">
$("#Unassign").live("click", function(){
$("#button").load($("#text").attr("href"));
return false;
});
</script>
<!--{{ subnets }}<hr /> <!--{{ subnets }}<hr />
{{ networks }} <hr /> {{ networks }} <hr />
{{ ports }} {{ ports }}
--> -->
{{ server }}
<!-- Main content --> <!-- Main content -->
<div class="row"> <div class="row">
<form class="form-horizontal" action="" method="post"> <form class="form-horizontal" action="" method="post">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<input type="hidden" name="floatingip" value="{{ floatingip.floatingips[0].floating_ip_address }}">
<div class="col-xs-4"> <div class="col-xs-4">
<div class="box box-solid"> <div class="box box-solid">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Floating IP Address</h3> <h3 class="box-title">Floating IP Address</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<h3> <span style="font-size: 167%;">
{{ floatingip.floatingips[0].floating_ip_address }} {{ floatingip.floatingips[0].floating_ip_address }}
</h3> </span>
</div> </div>
</div> </div>
</div> </div>
@ -53,14 +59,22 @@
<h3 class="box-title">Server</h3> <h3 class="box-title">Server</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<select name="server" class="form-control"> {% if floatingip.floatingips[0]['port_id'] %}
{% for server in servers %} <h3>
<option value="{{ server.id }}">{{ server.name }}</option> {% set server_name = nova.servers.get(neutron.list_ports(id=floatingip.floatingips[0]['port_id']).ports[0]['device_id']).name %}
{% endfor %} {% set server_id = nova.servers.get(neutron.list_ports(id=floatingip.floatingips[0]['port_id']).ports[0]['device_id']).id %}
</select> {{ server_name }}
{% if form.server.errors %} </h3>
<br /> {% else %}
<span class="text-red">{% for error in form.server.errors %} {{ error }} {% endfor %}</span> <select name="server" class="form-control">
{% for server in servers %}
<option value="{{ server.id }}">{{ server.name }}</option>
{% endfor %}
</select>
{% if form.server.errors %}
<br />
<span class="text-red">{% for error in form.server.errors %} {{ error }} {% endfor %}</span>
{% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -71,12 +85,19 @@
<h3 class="box-title">Action</h3> <h3 class="box-title">Action</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<button type="submit" name="submit" class="btn btn-primary btn-block btn-flat" value="reassign">Reassign</button> {% if floatingip.floatingips[0]['port_id'] %}
<a type="button" class="btn btn-primary" id="button"
href="{{ url_for('network.unassign_floatingip', id=floatingip.floatingips[0]['id'], server_id=server_id ) }}">
Unassign
</a>
{% else %}
<button type="submit" class="btn btn-primary">Reassign</button>
<button class="btn btn-danger">Release</button>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
<!-- /.row --> <!-- /.row -->
{%- endblock content %} {%- endblock content %}

View File

@ -55,7 +55,9 @@
<td>{{ floatingip['floating_ip_address'] }} </td> <td>{{ floatingip['floating_ip_address'] }} </td>
<td> <td>
{% if floatingip['port_id'] %} {% if floatingip['port_id'] %}
{{ nova.servers.get(neutron.list_ports(id=floatingip['port_id']).ports[0]['device_id']).name }} {% set server_name = nova.servers.get(neutron.list_ports(id=floatingip['port_id']).ports[0]['device_id']).name %}
{% set server_id = nova.servers.get(neutron.list_ports(id=floatingip['port_id']).ports[0]['device_id']).id %}
{{ server_name }}
{% endif %} {% endif %}
</td> </td>
<td> <td>
@ -67,15 +69,25 @@
<td> <td>
<div style="margin-bottom:10px;" class="btn-group"> <div style="margin-bottom:10px;" class="btn-group">
<button type="button" class="btn btn-default"> <button type="button" class="btn btn-default">
<a style="color:black" href="">Action</a> <a style="color:black" href="#">Action</a>
</button> </button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span> <span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span> <span class="sr-only">Toggle Dropdown</span>
</button> </button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li><a href="{{ url_for('network.assign_floatingip', id=floatingip['id']) }}">Reassign</a></li> <li>
<li><a href="">Unassign</a></li> <a href="{{ url_for('network.assign_floatingip', id=floatingip['id'] ) }}">
Reassign
</a>
</li>
{% if floatingip['port_id'] %}
<li>
<a href="{{ url_for('network.unassign_floatingip', id=floatingip['id'], server_id=server_id ) }}">
Unassign
</a>
</li>
{% endif %}
<li class="divider"></li> <li class="divider"></li>
<li><a style="color:red" href="#">Release</a></li> <li><a style="color:red" href="#">Release</a></li>
</ul> </ul>