@ -1,6 +1,6 @@
/ *
ztncui - ZeroTier network controller UI
Copyright ( C ) 2017 Key Networks ( https : //key-networks.com)
Copyright ( C ) 2017 - 2018 Key Networks ( https : //key-networks.com)
Licensed under GPLv3 - see LICENSE for details .
* /
@ -13,52 +13,68 @@ storage.initSync({dir: 'etc/storage'});
// ZT network controller home page
exports . index = async function ( req , res ) {
const page = 'controller_home' ;
const nav =
{
active : 'controller_home' ,
}
try {
zt _address = await zt . get _zt _address ( ) ;
res . render ( 'index' , { title : 'ztncui' , page: page , zt _address : zt _address } ) ;
res . render ( 'index' , { title : 'ztncui' , nav: nav , zt _address : zt _address } ) ;
} catch ( err ) {
res . render ( 'index' , { title : 'ztncui' ,
page: page , error : 'ERROR resolving ZT address: ' + err } ) ;
nav: nav , error : 'ERROR resolving ZT address: ' + err } ) ;
}
} ;
// Display list of all networks on this ZT network controller
exports . network _list = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
}
try {
networks = await zt . network _list ( ) ;
res . render ( 'networks' , { title : 'Networks on this controller' , page: page , networks : networks } ) ;
res . render ( 'networks' , { title : 'Networks on this controller' , nav: nav , networks : networks } ) ;
} catch ( err ) {
res . render ( 'networks' , { title : 'Networks on this controller' , page: page , error : 'Error retrieving list of networks on this controller: ' + err } ) ;
res . render ( 'networks' , { title : 'Networks on this controller' , nav: nav , error : 'Error retrieving list of networks on this controller: ' + err } ) ;
}
} ;
// Display detail page for specific network
exports . network _detail = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
const members = await zt . members ( req . params . nwid ) ;
res . render ( 'network_detail' , { title : 'Detail for network' , page: page , network : network , members : members } ) ;
res . render ( 'network_detail' , { title : 'Detail for network' , nav: nav , network : network , members : members } ) ;
} catch ( err ) {
res . render ( 'network_detail' , { title : 'Detail for network' , page: page , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'network_detail' , { title : 'Detail for network' , nav: nav , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
}
} ;
// Display Network create form on GET
exports . network _create _get = function ( req , res ) {
const page = 'add_network' ;
const nav =
{
active : 'add_network' ,
}
res . render ( 'network_create' , { title : 'Create network' , page : page } ) ;
res . render ( 'network_create' , { title : 'Create network' , nav: nav } ) ;
} ;
// Handle Network create on POST
exports . network _create _post = async function ( req , res ) {
const page = 'add_network' ;
const nav =
{
active : 'add_network' ,
}
req . checkBody ( 'name' , 'Network name required' ) . notEmpty ( ) ;
@ -70,66 +86,83 @@ exports.network_create_post = async function(req, res) {
const name = { name : req . body . name } ;
if ( errors ) {
res . render ( 'network_create' , { title : 'Create Network' , page: page , name : name , errors : errors } ) ;
res . render ( 'network_create' , { title : 'Create Network' , nav: nav , name : name , errors : errors } ) ;
return ;
} else {
try {
const network = await zt . network _create ( name ) ;
res . redirect ( '/controller/networks' ) ;
} catch ( err ) {
res . render ( 'network_detail' , { title : 'Create Network - error' , page: page , error : 'Error creating network ' + name . name } ) ;
res . render ( 'network_detail' , { title : 'Create Network - error' , nav: nav , error : 'Error creating network ' + name . name } ) ;
}
}
} ;
// Display Network delete form on GET
exports . network _delete _get = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
res . render ( 'network_delete' , { title : 'Delete network' , page : page ,
res . render ( 'network_delete' , { title : 'Delete network' , nav: nav ,
nwid : req . params . nwid , network : network } ) ;
} catch ( err ) {
res . render ( 'network_delete' , { title : 'Delete network' , page: page , error : 'Error resolving network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'network_delete' , { title : 'Delete network' , nav: nav , error : 'Error resolving network ' + req . params . nwid + ': ' + err } ) ;
}
} ;
// Handle Network delete on POST
exports . network _delete _post = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
try {
const network = await zt . network _delete ( req . params . nwid ) ;
res . render ( 'network_delete' , { title : 'Delete network' , page : page , network : network } ) ;
res . render ( 'network_delete' , { title : 'Delete network' , nav: nav , network : network } ) ;
} catch ( err ) {
res . render ( 'network_delete' , { title : 'Delete network' , page: page , error : 'Error deleting network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'network_delete' , { title : 'Delete network' , nav: nav , error : 'Error deleting network ' + req . params . nwid + ': ' + err } ) ;
}
} ;
// Network object GET
exports . network _object = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
res . render ( req . params . object , { title : req . params . object , page : page , network : network } , function ( err , html ) {
nav . whence = '/controller/network/' + network . nwid ;
res . render ( req . params . object , { title : req . params . object , nav : nav , network : network } , function ( err , html ) {
if ( err ) {
if ( err . message . indexOf ( 'Failed to lookup view' ) !== - 1 ) {
return res . render ( 'not_implemented' , { title : req . params . object , page: page , network : network } ) ;
return res . render ( 'not_implemented' , { title : req . params . object , nav: nav , network : network } ) ;
}
throw err ;
}
res . send ( html ) ;
} ) ;
} catch ( err ) {
res . render ( req . params . object , { title : req . params . object , page: page , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( req . params . object , { title : req . params . object , nav: nav , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
}
}
// Handle Network rename form on POST
exports . name = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
req . checkBody ( 'name' , 'Network name required' ) . notEmpty ( ) ;
req . sanitize ( 'name' ) . escape ( ) ;
@ -142,16 +175,16 @@ exports.name = async function(req, res) {
if ( errors ) {
try {
const network = await zt . network _detail ( req . params . nwid ) ;
res . render ( 'name' , { title : 'Rename network' , page: page , network : network , name : name , errors : errors } ) ;
res . render ( 'name' , { title : 'Rename network' , nav: nav , network : network , name : name , errors : errors } ) ;
} catch ( err ) {
res . render ( 'name' , { title : 'Rename network' , page: page , error : 'Error resolving network detail for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'name' , { title : 'Rename network' , nav: nav , error : 'Error resolving network detail for network ' + req . params . nwid + ': ' + err } ) ;
}
} else {
try {
const network = await zt . network _object ( req . params . nwid , name ) ;
res . redirect ( '/controller/networks' ) ;
} catch ( err ) {
res . render ( 'name' , { title : 'Rename network' , page: page , error : 'Error renaming network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'name' , { title : 'Rename network' , nav: nav , error : 'Error renaming network ' + req . params . nwid + ': ' + err } ) ;
}
}
@ -159,7 +192,11 @@ exports.name = async function(req, res) {
// ipAssignmentPools POST
exports . ipAssignmentPools = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
req . checkBody ( 'ipRangeStart' , 'IP range start required' ) . notEmpty ( ) ;
req . checkBody ( 'ipRangeStart' , 'IP range start needs a valid IPv4 or IPv6 address' ) . isIP ( ) ;
@ -181,16 +218,18 @@ exports.ipAssignmentPools = async function(req, res) {
if ( errors ) {
try {
const network = await zt . network _detail ( req . params . nwid ) ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , page : page , ipAssignmentPool : ipAssignmentPool , network : network , errors : errors } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , nav : nav , ipAssignmentPool : ipAssignmentPool , network : network , errors : errors } ) ;
} catch ( err ) {
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , page: page , error : 'Error resolving network detail for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , nav: nav , error : 'Error resolving network detail for network ' + req . params . nwid + ': ' + err } ) ;
}
} else {
try {
const network = await zt . ipAssignmentPools ( req . params . nwid , ipAssignmentPool , 'add' ) ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , page : page , ipAssignmentPool : ipAssignmentPool , network : network } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , nav : nav , ipAssignmentPool : ipAssignmentPool , network : network } ) ;
} catch ( err ) {
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , page: page , error : 'Error applying IP Assignment Pools for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , nav: nav , error : 'Error applying IP Assignment Pools for network ' + req . params . nwid + ': ' + err } ) ;
}
}
}
@ -202,7 +241,11 @@ isValidPrefix = function(str, max) {
// routes POST
exports . routes = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
req . checkBody ( 'target' , 'Target network is required' ) . notEmpty ( ) ;
req . sanitize ( 'target' ) . trim ( ) ;
@ -242,16 +285,18 @@ exports.routes = async function (req, res) {
if ( errors ) {
try {
const network = await zt . network _detail ( req . params . nwid ) ;
res . render ( 'routes' , { title : 'routes' , page : page , route : route , network : network , errors : errors } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'routes' , { title : 'routes' , nav : nav , route : route , network : network , errors : errors } ) ;
} catch ( err ) {
res . render ( 'routes' , { title : 'routes' , page: page , error : 'Error resolving network detail' } ) ;
res . render ( 'routes' , { title : 'routes' , nav: nav , error : 'Error resolving network detail' } ) ;
}
} else {
try {
const network = await zt . routes ( req . params . nwid , route , 'add' ) ;
res . render ( 'routes' , { title : 'routes' , page : page , route : route , network : network } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'routes' , { title : 'routes' , nav : nav , route : route , network : network } ) ;
} catch ( err ) {
res . render ( 'routes' , { title : 'routes' , page: page , error : 'Error adding route for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'routes' , { title : 'routes' , nav: nav , error : 'Error adding route for network ' + req . params . nwid + ': ' + err } ) ;
}
}
@ -259,7 +304,11 @@ exports.routes = async function (req, res) {
// route_delete GET
exports . route _delete = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
const route =
{
@ -270,15 +319,20 @@ exports.route_delete = async function (req, res) {
try {
const network = await zt . routes ( req . params . nwid , route , 'delete' ) ;
res . render ( 'routes' , { title : 'routes' , page : page , route : route , network : network } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'routes' , { title : 'routes' , nav : nav , route : route , network : network } ) ;
} catch ( err ) {
res . render ( 'routes' , { title : 'routes' , page: page , error : 'Error deleting route for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'routes' , { title : 'routes' , nav: nav , error : 'Error deleting route for network ' + req . params . nwid + ': ' + err } ) ;
}
}
// ipAssignmentPool_delete GET
exports . ipAssignmentPool _delete = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
const ipAssignmentPool =
{
@ -289,15 +343,20 @@ exports.ipAssignmentPool_delete = async function (req, res) {
try {
const network = await zt . ipAssignmentPools ( req . params . nwid , ipAssignmentPool , 'delete' ) ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , page : page , ipAssignmentPool : ipAssignmentPool , network : network } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , nav : nav , ipAssignmentPool : ipAssignmentPool , network : network } ) ;
} catch ( err ) {
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , page: page , error : 'Error deleting IP Assignment Pool for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'ipAssignmentPools' , { title : 'ipAssignmentPools' , nav: nav , error : 'Error deleting IP Assignment Pool for network ' + req . params . nwid + ': ' + err } ) ;
}
}
// v4AssignMode POST
exports . v4AssignMode = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
const v4AssignMode =
{
@ -306,15 +365,20 @@ exports.v4AssignMode = async function (req, res) {
try {
const network = await zt . network _object ( req . params . nwid , v4AssignMode ) ;
res . render ( 'v4AssignMode' , { title : 'v4AssignMode' , page : page , network : network } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'v4AssignMode' , { title : 'v4AssignMode' , nav : nav , network : network } ) ;
} catch ( err ) {
res . render ( 'v4AssignMode' , { title : 'v4AssignMode' , page: page , error : 'Error applying v4AssignMode for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'v4AssignMode' , { title : 'v4AssignMode' , nav: nav , error : 'Error applying v4AssignMode for network ' + req . params . nwid + ': ' + err } ) ;
}
}
// v6AssignMode POST
exports . v6AssignMode = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
const v6AssignMode =
{
@ -328,76 +392,103 @@ exports.v6AssignMode = async function (req, res) {
try {
const network = await zt . network _object ( req . params . nwid , v6AssignMode ) ;
res . render ( 'v6AssignMode' , { title : 'v6AssignMode' , page : page , network : network } ) ;
nav . whence = '/controller/network/' + network . nwid ;
res . render ( 'v6AssignMode' , { title : 'v6AssignMode' , nav : nav , network : network } ) ;
} catch ( err ) {
res . render ( 'v6AssignMode' , { title : 'v6AssignMode' , page: page , error : 'Error applying v6AssignMode for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'v6AssignMode' , { title : 'v6AssignMode' , nav: nav , error : 'Error applying v6AssignMode for network ' + req . params . nwid + ': ' + err } ) ;
}
}
// Display detail page for specific member
exports . member _detail = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
const member = await zt . member _detail ( req . params . nwid , req . params . id ) ;
res . render ( 'member_detail' , { title : 'Network member detail' , page : page , network : network , member : member } ) ;
nav . whence = '/controller/network/' + network . nwid + '/members' ;
res . render ( 'member_detail' , { title : 'Network member detail' , nav : nav , network : network , member : member } ) ;
} catch ( err ) {
res . render ( req . params . object , { title : req . params . object , page: page , error : 'Error resolving detail for member ' + req . params . id + ' of network ' + req . params . nwid + ': ' + err } ) ;
res . render ( req . params . object , { title : req . params . object , nav: nav , error : 'Error resolving detail for member ' + req . params . id + ' of network ' + req . params . nwid + ': ' + err } ) ;
}
} ;
// Member object GET
exports . member _object = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
const member = await zt . member _detail ( req . params . nwid , req . params . id ) ;
res . render ( req . params . object , { title : req . params . object , page : page , network : network , member : member } , function ( err , html ) {
const name = await storage . getItem ( member . id ) ;
if ( ! name ) name = '' ;
member . name = name ;
nav . whence = '/controller/network/' + network . nwid + '/members' ;
res . render ( req . params . object , { title : req . params . object , nav : nav , network : network , member : member } , function ( err , html ) {
if ( err ) {
if ( err . message . indexOf ( 'Failed to lookup view' ) !== - 1 ) {
return res . render ( 'not_implemented' , { title : req . params . object , page : page , network : network , member : member } ) ;
return res . render ( 'not_implemented' , { title : req . params . object , nav: nav , network : network , member : member } ) ;
}
throw err ;
}
res . send ( html ) ;
} ) ;
} catch ( err ) {
res . render ( req . params . object , { title : req . params . object , page: page , error : 'Error resolving detail for member ' + req . params . id + ' of network ' + req . params . nwid + ': ' + err } ) ;
res . render ( req . params . object , { title : req . params . object , nav: nav , error : 'Error resolving detail for member ' + req . params . id + ' of network ' + req . params . nwid + ': ' + err } ) ;
}
}
// Member authorized POST
exports . member _authorized = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
const authorized = { authorized : req . body . authorized } ;
try {
const network = await zt . network _detail ( req . params . nwid ) ;
const member = await zt . member _object ( req . params . nwid , req . params . id , authorized ) ;
res . render ( 'authorized' , { title : 'authorized' , page : page , network : network , member : member } ) ;
nav . whence = '/controller/network/' + network . nwid + '/members' ;
res . render ( 'authorized' , { title : 'authorized' , nav : nav , network : network , member : member } ) ;
} catch ( err ) {
res . render ( 'authorized' , { title : 'authorized' , page: page , error : 'Error authorizing member ' + req . params . id + ' on network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'authorized' , { title : 'authorized' , nav: nav , error : 'Error authorizing member ' + req . params . id + ' on network ' + req . params . nwid + ': ' + err } ) ;
}
}
// Easy network setup GET
exports . easy _get = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , page : page , network : network } ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , nav: nav , network : network } ) ;
} catch ( err ) {
res . render ( 'network_easy' , { title : 'Easy setup of network' , page: page , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , nav: nav , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
}
}
// Easy network setup POST
exports . easy _post = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
req . checkBody ( 'networkCIDR' , 'Network address is required' ) . notEmpty ( ) ;
req . sanitize ( 'networkCIDR' ) . trim ( ) ;
@ -447,23 +538,27 @@ exports.easy_post = async function(req, res) {
v4AssignMode : v4AssignMode
} ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , page: page , network : network , errors : errors } ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , nav: nav , network : network , errors : errors } ) ;
} else {
try {
const network = await zt . network _easy _setup ( req . params . nwid ,
routes ,
ipAssignmentPools ,
v4AssignMode ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , page: page , network : network , message : 'Network setup succeeded' } ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , nav: nav , network : network , message : 'Network setup succeeded' } ) ;
} catch ( err ) {
res . render ( 'network_easy' , { title : 'Easy setup of network' , page: page , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
res . render ( 'network_easy' , { title : 'Easy setup of network' , nav: nav , error : 'Error resolving detail for network ' + req . params . nwid + ': ' + err } ) ;
}
}
}
// Easy members auth GET or POST
exports . members = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : '/controller/networks'
}
let errors = null ;
@ -520,18 +615,22 @@ exports.members = async function(req, res) {
members . push ( member ) ;
}
res . render ( 'members' , { title : 'Members of this network' , page: page ,
res . render ( 'members' , { title : 'Members of this network' , nav: nav ,
network : network , members : members , errors : errors } ) ;
} catch ( err ) {
res . render ( 'members' , { title : 'Members of this network' , page: page ,
res . render ( 'members' , { title : 'Members of this network' , nav: nav ,
error : 'Error resolving detail for network ' + req . params . nwid
+ ': ' + err } ) ;
}
}
// Member delete GET and POST
// Member delete GET or POST
exports . member _delete = async function ( req , res ) {
const page = 'networks' ;
const nav =
{
active : 'networks' ,
whence : ''
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
@ -548,12 +647,109 @@ exports.member_delete = async function(req, res) {
}
if ( ! name ) name = '' ;
member . name = name ;
nav . whence = '/controller/network/' + network . nwid + '/members' ;
res . render ( 'member_delete' , { title : 'Delete member from ' + network . name ,
network : network , member : member } ) ;
} catch ( err ) {
res . render ( 'member_delete' , { title : 'Delete member from network' , page : page ,
res . render ( 'member_delete' , { title : 'Delete member from network' , nav : nav ,
error : 'Error resolving detail for member ' + req . params . id
+ ' of network ' + req . params . nwid + ': ' + err } ) ;
}
}
// ipAssignment delete GET
exports . delete _ip = async function ( req , res ) {
const nav =
{
active : 'networks' ,
whence : ''
}
try {
const network = await zt . network _detail ( req . params . nwid ) ;
let member = await zt . member _detail ( req . params . nwid , req . params . id ) ;
nav . whence = '/controller/network/' + network . nwid + '/members' ;
const name = await storage . getItem ( member . id ) ;
if ( ! name ) name = '' ;
member . name = name ;
if ( req . params . index ) {
member = await zt . ipAssignmentDelete ( network . nwid , member . id ,
req . params . index ) ;
res . redirect ( '/controller/network/' + network . nwid + '/member/' +
member . id + '/ipAssignments' ) ;
}
res . render ( 'ipAssignments' , { title : 'ipAssignments ' + network . name ,
index : req . params . index , network : network , member : member } ) ;
} catch ( err ) {
res . render ( 'ipAssignments' , { title : 'ipAssignments' , nav : nav ,
error : 'Error resolving detail for member ' + req . params . id
+ ' of network ' + req . params . nwid + ': ' + err } ) ;
}
}
// ipAssignments POST
exports . assign _ip = async function ( req , res ) {
const nav =
{
active : 'networks' ,
whence : ''
}
try {
var network = await zt . network _detail ( req . params . nwid ) ;
} catch ( err ) {
throw err ;
}
req . checkBody ( 'ipAddress' , 'IP address required' ) . notEmpty ( ) ;
req . checkBody ( 'ipAddress' , 'IP address must be a valid IPv4 or IPv6 address' ) . isIP ( ) ;
req . checkBody ( 'ipAddress' , 'IP address must fall within a managed route' )
. custom ( value => {
let ipAddressInManagedRoute = false ;
network . routes . forEach ( function ( item ) {
let ipv4 = new ipaddr . Address4 ( value ) ;
console . log ( 'ipv4 = ' + JSON . stringify ( ipv4 ) ) ;
let target4 = new ipaddr . Address4 ( item . target ) ;
console . log ( 'target4 = ' + JSON . stringify ( target4 ) ) ;
if ( ipv4 . isValid ( ) && target4 . isValid ( ) ) {
if ( ipv4 . isInSubnet ( target4 ) ) ipAddressInManagedRoute = true ;
}
let ipv6 = new ipaddr . Address6 ( value ) ;
console . log ( 'ipv6 = ' + JSON . stringify ( ipv6 ) ) ;
let target6 = new ipaddr . Address6 ( item . target ) ;
console . log ( 'target6 = ' + JSON . stringify ( target6 ) ) ;
if ( ipv6 . isValid ( ) && target6 . isValid ( ) ) {
if ( ipv6 . isInSubnet ( target6 ) ) ipAddressInManagedRoute = true ;
}
} ) ;
return ipAddressInManagedRoute ;
} ) ;
req . sanitize ( 'ipAddress' ) . escape ( ) ;
req . sanitize ( 'ipAddress' ) . trim ( ) ;
const errors = req . validationErrors ( ) ;
const ipAssignment = { ipAddress : req . body . ipAddress } ;
try {
let member = await zt . member _detail ( req . params . nwid , req . params . id ) ;
nav . whence = '/controller/network/' + network . nwid + '/members' ;
if ( ! errors ) {
member = await zt . ipAssignmentAdd ( network . nwid , member . id , ipAssignment ) ;
}
const name = await storage . getItem ( member . id ) ;
if ( ! name ) name = '' ;
member . name = name ;
res . render ( 'ipAssignments' , { title : 'ipAssignments' , nav : nav ,
ipAssignment : ipAssignment , network : network , member : member ,
errors : errors } ) ;
} catch ( err ) {
res . render ( 'ipAssignments' , { title : 'ipAssignments' , nav : nav ,
error : 'Error resolving detail for member ' + req . params . id
+ ' of network ' + req . params . nwid + ': ' + err } ) ;
}
}