simple proxmox

This commit is contained in:
2020-08-26 15:41:37 -04:00
parent f7cee0239e
commit f18967ce8b
26 changed files with 964 additions and 2504 deletions

79
nodejs/views/chat.ejs Normal file
View File

@ -0,0 +1,79 @@
<%- include('top') %>
<script id="rowTemplate" type="text/html">
<p>
<b>{{ uid }}:</b> {{message}}
</p>
</script>
<script type="text/javascript">
var publishTopic = function(btn){
event.preventDefault(); // avoid to execute the actual submit of the form.
var $form = $(btn).closest( '[action]' ); // gets the 'form' parent
var formData = $form.find( '[name]' ).serializeObject();
if( !$form.validate()) {
app.util.actionMessage('Please fix the form errors.', $form, 'danger')
return false;
}
console.log('formData', formData)
app.publish('p2p-chat', {
uid: app.auth.user.uid,
message: formData.message
})
$form.trigger("reset");
};
$(document).ready(function(){
app.subscribe("p2p-chat", function(data, topic){
var rowTemplate = $('#rowTemplate').html();
var $target = $('#tableAJAX');
user_row = Mustache.render(rowTemplate, data);
$target.append(user_row);
});
});
</script>
<div class="row" style="display:none">
<div class="col-md-4">
<div class="card shadow-lg">
<div class="card-header">
<i class="fas fa-layer-plus"></i>
Chat
</div>
<div class="card-header actionMessage" style="display:none"></div>
<div class="card-body">
<form action='__internal__' onsubmit="publishTopic(this)">
<div class="form-group">
<label class="control-label">message</label>
<textarea class="form-control shadow" name="message" placeholder="{...}" validate=":1"></textarea>
</div>
<button type="submit" class="btn btn-outline-dark">Send</button>
</form>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card shadow-lg">
<div class="card-header">
<i class="fad fa-users-class"></i>
Incoming Chats
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<div class="" id="tableAJAX">
</div>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

View File

@ -1,25 +0,0 @@
module.exports = {
subject: 'Password reset for Theta 42 account',
message: `
<h2> Theta 42 account</h2>
<p>
Hello {{ user.givenName }},
</p>
<p>
You have asked to reset the password for user name <b>{{ user.uid }}</b> . Please
click the link below to complete this request. If this was done in errror,
please ignore this email.
</p>
<p>
{{ link }}
</p>
</p>
Thank you,<br />
Theta 42
</p>
`
};

View File

@ -1,24 +0,0 @@
module.exports = {
subject: 'Validate email for Theta 42 account',
message: `
<h2> Theta 42 account</h2>
<p>
Welcome,
</p>
<p>
We need to verify the provided email address in order to continue. Please
follow the link below to verify this email address:
</p>
<p>
{{ link }}
</p>
</p>
Thank you,<br />
Theta 42
</p>
`
};

View File

@ -1,34 +0,0 @@
module.exports = {
subject: 'Welcome to Theta 42!',
message: `
<p>
Welcome {{user.givenName}},
</p>
<p>
Your new Theta 42 Single sign-on account is ready to use. Here is some
information to get you started.
</p>
<p>
Your username is <b>{{user.uid}}</b>
</p>
<p>
You can manage your account at https://sso.theta42.com
</p>
<p>
You account is ready to be used now, test it by SSHing into the Theta 42
jump host \`ssh {{user.uid}}@718it.biz\`
</p>
<p>
The SSO service is still in beta, so please report any bugs you may find!
You will be notified of new features and services as they become available.
</p>
Thank you,<br />
Theta 42
</p>
`
};

View File

@ -1,134 +0,0 @@
<%- include('top') %>
<script id="rowTemplate" type="text/html">
<p>
<div class="card shadow">
<div class="card-header">
<i class="fad fa-users-class"></i>
Group: {{ cn }}
</div>
<div class="card-body">
<p>
{{ description }}
</p>
<p>
<ul class="list-group">
{{ #member }}
<li class="list-group-item shadow">
<i class="fad fa-user"></i> {{ uid }}
<button type="button" action="group/{{groupCN}}/{{uid}}" method="delete" onclick="formAJAX(this)" evalAJAX="tableAJAX(data.message)" class="btn btn-sm btn-danger float-right">
<i class="fad fa-user-slash"></i>
</button>
</li>
{{ /member }}
</ul>
</p>
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fad fa-user-plus"></i>
</button>
<div class="dropdown-menu shadow-lg" aria-labelledby="dropdownMenuButton">
{{ #toAdd }}{{#.}}
<a class="dropdown-item" action="group/{{groupCN}}/{{uid}}" method="put" onclick="formAJAX(this)" evalAJAX="tableAJAX(data.message)">
<i class="fad fa-user"></i> {{uid}}
</a>
{{/.}}{{ /toAdd }}
</div>
<button type="button" onclick="app.group.remove({cn: '{{cn}}'}, function(){tableAJAX('Group {{cn}} deleted.')})" class="btn btn-danger float-right">
<i class="fad fa-trash"></i>
</button>
</div>
</div>
</p>
</script>
<script type="text/javascript">
var userlist;
function getUserList(callback){
app.user.list(function(error, data){
userlist = data.results;
callback()
})
}
function tableAJAX(actionMessage){
var rowTemplate = $('#rowTemplate').html();
var $target = $('#tableAJAX');
$target.html('').hide();
app.util.actionMessage('Refreshing user list...', $target);
app.group.list(function(error, data){
$.each( data.results, function(key, value) {
// console.log(value.member)
value.toAdd = userlist.map(function(user){
if(!value.member.includes(user.dn)) return user;
})
value.member = value.member.map(function(user){
return {
dn: user,
uid: user.match(/cn=[a-zA-Z0-9\_\-\@\.]+/)[0].replace('cn=', '')
}
})
value.groupCN = value.cn;
user_row = Mustache.render(rowTemplate, value);
$target.append(user_row);
});
$target.fadeIn('slow');
app.util.actionMessage(actionMessage || '', $target, 'info');
});
}
$(document).ready(function(){
getUserList(tableAJAX);
});
</script>
<div class="row" style="display:none">
<div class="col-md-4">
<div class="card shadow-lg">
<div class="card-header">
<i class="fas fa-layer-plus"></i>
Add new group
</div>
<div class="card-header actionMessage" style="display:none"></div>
<div class="card-body">
<form action="group/" method="post" onsubmit="formAJAX(this)" evalAJAX="tableAJAX('')">
<div class="form-group">
<label class="control-label">Name</label>
<input type="text" class="form-control shadow" name="name" placeholder="app_gitea_admin" validate=":3" />
</div>
<div class="form-group">
<label class="control-label">Description</label>
<textarea class="form-control shadow" name="description" placeholder="Admin group for gitea app" validate=":3"></textarea>
</div>
<button type="submit" class="btn btn-outline-dark">Add</button>
</form>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card shadow-lg">
<div class="card-header">
<i class="fad fa-users-class"></i>
Group list
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<div class="" id="tableAJAX">
</div>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

View File

@ -1,39 +0,0 @@
<%- include('top') %>
<script type="text/javascript">
function tableAJAX(message){
app.util.actionMessage(message);
}
$(document).ready(function(){
$('form').attr('action', 'auth/invite/<%= invite.token %>/<%= invite.mail_token %>').attr('evalAJAX', 'location.replace("/login");')
$('[name="mail"').val('<%= invite.mail %>').prop("disabled", true);
});
</script>
<style type="text/css">
div.form-group:hover {
-ms-transform: scale(1.02);
-webkit-transform: scale(1.02);
transform: scale(1.02);
}
</style>
<div class="row" style="display:none">
<div class="col-md-12">
<div class="card shadow-lg">
<div class="card-header">
Add new user
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Invited By: <b><%= invite.created_by %></b>, <%= invite.created_on %>
</p>
<%- include('user_form') %>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

View File

@ -1,59 +0,0 @@
<%- include('top') %>
<script type="text/javascript">
var emailSent = function(){
$('#email_card .card-body').html("<h1>Thank you!</h1><p>Check your mail</p>")
}
$(document).ready(function(){
});
</script>
<style type="text/css">
div.form-group:hover {
-ms-transform: scale(1.02);
-webkit-transform: scale(1.02);
transform: scale(1.02);
}
</style>
<div class="row">
<div id="email_card" class="card-deck">
<div class="shadow-lg card mb-3">
<div class="card-header">
Validate Email
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Invited By: <b><%= invite.created_by %></b>, <%= invite.created_on %>.
</p>
<p>
Please enter a valid email address. A link will be sent to
the supplied address to complete the registration process.
</p>
<p>
The supplied email will also be used as the linked email for
the new user.
</p>
<form action="auth/invite/<%= invite.token %>" onsubmit="formAJAX(this)" evalAJAX="emailSent()">
<div class="form-group">
<label class="control-label">Email</label>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-at"></i></span>
</div>
<input type="email" name="mail" class="form-control" placeholder="jsmith@gmail.com" validate="email:3" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-paper-plane"></i> Send It!</button>
</form>
</div>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

View File

@ -3,7 +3,7 @@
app.auth.isLoggedIn(function(error, isLoggedIn){
if(isLoggedIn){
window.location.href = app.util.getUrlParameter('redirect') || '/';
window.location.href = app.util.getUrlParameter('redirect') || '/topics';
}
})
@ -48,53 +48,6 @@
</form>
</div>
</div>
<div class="shadow-lg card border-danger mb-3">
<div class="card-header shadow">
Social Login
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<h3>Coming soon!</h3>
<p>
<ul class="list-group">
<li class="list-group-item"><i class="fab fa-google"></i> Login with google OATH</li>
<li class="list-group-item"><i class="fab fa-github"></i> Login with github OATH</li>
<li class="list-group-item"><i class="fab fa-facebook"></i> Login with facebook OATH</li>
</ul>
</p>
</div>
</div>
<div class="shadow-lg card mb-3">
<div class="card-header shadow">
Password Reset
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Forgot your password? Or your user name? No problem! Just
enter you email address below and if you are in our system,
we will email with the required information to get back up
and running!
</p>
<form action="auth/resetpassword" onsubmit="formAJAX(this)">
<input type="hidden" name="redirect" value="<%= redirect %>">
<div class="form-group">
<label class="control-label">Email</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-at"></i></span>
</div>
<input type="email" name="mail" class="form-control" placeholder="jsmith@gmail.com" validate="email:3" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-question"></i> Help me!</button>
</form>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

114
nodejs/views/proxmox.ejs Normal file
View File

@ -0,0 +1,114 @@
<%- include('top') %>
<script type="text/javascript">
var proxmoxSites = {};
function formatBytes(a,b=2){if(0===a)return"0 Bytes";const c=0>b?0:b,d=Math.floor(Math.log(a)/Math.log(1024));return parseFloat((a/Math.pow(1024,d)).toFixed(c))+" "+["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"][d]}
var parseNodeData = function(data){
cluster = data.data
cluster.onlineCount = 0;
cluster.cpu = 0
cluster.maxcpu = 0
cluster.maxmem = 0
cluster.mem = 0
for(let node of data.data.node){
// console.log('parse', node)
if(node.status === "offline") continue;
cluster.onlineCount++
cluster.cpu += node.cpu
cluster.maxcpu += node.maxcpu
cluster.maxmem += node.maxmem
cluster.mem += node.mem
}
cluster.cpu = parseFloat(((cluster.cpu/cluster.onlineCount)*100).toFixed(2));
cluster.maxmem = formatBytes(cluster.maxmem)
cluster.mem = formatBytes(cluster.mem)
$.extend(data.data, cluster);
return data;
}
$(document).ready(function(){
app.subscribe('proxmox-cluster', function(data){
if(!proxmoxSites[data.vpnSite.name]){
let index = $.scope.proxmox.push(parseNodeData(data));
proxmoxSites[data.vpnSite.name] = {
data:data,
index: index
}
}else{
$.scope.proxmox.update(proxmoxSites[data.vpnSite.name].index, parseNodeData(data));
}
});
});
</script>
<div class="row">
<div class="shadow-lg card mb-3" jq-repeat="proxmox">
<div class="card-header">
{{ vpnSite.name }}
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
Nodes online {{data.onlineCount}} of {{data.node.length}} <br />
CPU: {{data.cpu}}% of {{data.maxcpu}} cores <br />
Ram: {{data.mem}} of {{data.maxmem}}
<ul>
{{#data.lxc}}
<li>{{name}} -- {{status}}</li>
{{/data.lxc}}
</ul>
</div>
</div>
</div>
<!-- <div id="email_card" class="card-deck">
<div class="shadow-lg card mb-3">
<div class="card-header">
Validate Email
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Invited By: <b></b>,.
</p>
<p>
Please enter a valid email address. A link will be sent to
the supplied address to complete the registration process.
</p>
<p>
The supplied email will also be used as the linked email for
the new user.
</p>
<form action="auth/invite/" onsubmit="formAJAX(this)" evalAJAX="emailSent()">
<div class="form-group">
<label class="control-label">Email</label>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-at"></i></span>
</div>
<input type="email" name="mail" class="form-control" placeholder="jsmith@gmail.com" validate="email:3" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-paper-plane"></i> Send It!</button>
</form>
</div>
</div>
</div>
</div> -->
<%- include('bottom') %>

View File

@ -3,19 +3,22 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>SSO Manager - Theta 42</title>
<title>VPN-p2p - Theta 42</title>
<!-- CSS are placed here -->
<!-- <link rel='stylesheet' href='/static/css/bootstrap.min.css' /> -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel='stylesheet' href='/static/css/styles.css' />
<!-- Scripts are placed here -->
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
<!-- <script type="text/javascript" src='/static/js/jquery.min.js'></script> -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!-- <script type="text/javascript" src='/static/js/bootstrap.min.js'></script> -->
<script src="https://kit.fontawesome.com/4625ee80a2.js" crossorigin="anonymous"></script>
<script type="text/javascript" src='/static/js/mustache.min.js'></script>
<script src="//stuff.718it.biz/jq-repeat.js"></script>
<script type="text/javascript" src="/static/js/app.js"></script>
<script type="text/javascript" src="/static/js/val.js"></script>
<script type="text/javascript" src="/static/js/moment.js"></script>
@ -28,11 +31,10 @@
</head>
<body>
<header class="shadow d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
<h5 class="hover-effect my-0 mr-md-auto font-weight-normal">SSO Manager - Theta 42</h5>
<h5 class="hover-effect my-0 mr-md-auto font-weight-normal">VPN p2p - Theta 42</h5>
<nav class="my-2 my-md-0 mr-md-3">
<a class="text-dark hover-effect" href="/"><i class="fad fa-tachometer-alt-fastest"></i> Home</a>
<a class="text-dark hover-effect" href="/users"><i class="fad fa-users"></i> Users</a>
<a class="text-dark hover-effect" href="/groups"><i class="fad fa-users-class"></i> Groups</a>
<a class="text-dark hover-effect" href="/topics"><i class="fad fa-tachometer-alt-fastest"></i> Topics</a>
<a class="text-dark hover-effect" href="/chat"><i class="fad fa-tachometer-alt-fastest"></i> Chat</a>
</nav>
<a class="hover-effect btn btn-outline-primary" onclick="app.auth.logOut(e => window.location.href='/')"><i class="fas fa-sign-out"></i> Log Out</a>

88
nodejs/views/topics.ejs Normal file
View File

@ -0,0 +1,88 @@
<%- include('top') %>
<script id="rowTemplate" type="text/html">
<p>
<div class="card shadow">
<div class="card-header">
<i class="fad fa-users-class"></i>
<b>Topic:</b> {{ topic }}
</div>
<div class="card-body">
{{ data }}
</div>
</div>
</p>
</script>
<script type="text/javascript">
var publishTopic = function(btn){
event.preventDefault(); // avoid to execute the actual submit of the form.
var $form = $(btn).closest( '[action]' ); // gets the 'form' parent
var formData = $form.find( '[name]' ).serializeObject();
if( !$form.validate()) {
app.util.actionMessage('Please fix the form errors.', $form, 'danger')
return false;
}
app.publish(formData.topic, JSON.parse(formData.data))
$form.trigger("reset");
app.util.actionMessage('Topic '+formData.topic+' published!', $form, 'success'); //re-populate table
};
$(document).ready(function(){
app.subscribe(/./g, function(data, topic){
var rowTemplate = $('#rowTemplate').html();
var $target = $('#tableAJAX');
user_row = Mustache.render(rowTemplate, {topic, data: JSON.stringify(data)});
$target.append(user_row);
$target.fadeIn('slow');
});
});
</script>
<div class="row" style="display:none">
<div class="col-md-4">
<div class="card shadow-lg">
<div class="card-header">
<i class="fas fa-layer-plus"></i>
Publish
</div>
<div class="card-header actionMessage" style="display:none"></div>
<div class="card-body">
<form action="group/" method="post" onsubmit="publishTopic(this)">
<div class="form-group">
<label class="control-label">Topic</label>
<input type="text" class="form-control shadow" name="topic" placeholder="app_gitea_admin" validate=":3" />
</div>
<div class="form-group">
<label class="control-label">JSON</label>
<textarea class="form-control shadow" name="data" placeholder="{...}" validate=":3"></textarea>
</div>
<button type="submit" class="btn btn-outline-dark">Publish</button>
</form>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card shadow-lg">
<div class="card-header">
<i class="fad fa-users-class"></i>
Incoming Topics
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<div class="" id="tableAJAX">
</div>
</div>
</div>
</div>
</div>
<%- include('bottom') %>