2015-07-03 11:29:11 +02:00
// Some configuration values are complex strings -
// so we need parsers/generators for them.
Ext . define ( 'PVE.Parser' , { statics : {
// this class only contains static functions
2018-05-04 11:53:34 +02:00
parseACME : function ( value ) {
if ( ! value ) {
return ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; //continue
}
var match _res ;
if ( ( match _res = p . match ( /^(?:domains=)?((?:[a-zA-Z0-9\-\.]+[;, ]?)+)$/ ) ) !== null ) {
res . domains = match _res [ 1 ] . split ( /[;, ]/ ) ;
} else {
errors = true ;
return false ;
}
} ) ;
if ( errors || ! res ) {
return ;
}
return res ;
} ,
2016-03-09 15:57:15 +01:00
parseBoolean : function ( value , default _value ) {
2016-04-29 12:06:26 +02:00
if ( ! Ext . isDefined ( value ) ) {
2016-03-09 15:57:15 +01:00
return default _value ;
2016-04-29 12:06:26 +02:00
}
2016-03-09 15:57:15 +01:00
value = value . toLowerCase ( ) ;
2016-04-29 12:06:27 +02:00
return value === '1' ||
2016-03-09 15:57:15 +01:00
value === 'on' ||
value === 'yes' ||
value === 'true' ;
} ,
2018-08-01 20:29:06 +02:00
parsePropertyString : function ( value , defaultKey ) {
var res = { } ,
2018-08-02 15:58:57 +02:00
error ;
2018-08-01 20:29:06 +02:00
2019-10-04 16:07:49 +02:00
if ( typeof value !== 'string' || value === '' ) {
return res ;
}
2018-08-01 20:29:06 +02:00
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
var kv = p . split ( '=' , 2 ) ;
if ( Ext . isDefined ( kv [ 1 ] ) ) {
res [ kv [ 0 ] ] = kv [ 1 ] ;
} else if ( Ext . isDefined ( defaultKey ) ) {
if ( Ext . isDefined ( res [ defaultKey ] ) ) {
2018-08-02 15:58:57 +02:00
error = 'defaultKey may be only defined once in propertyString' ;
return false ; // break
2018-08-01 20:29:06 +02:00
}
res [ defaultKey ] = kv [ 0 ] ;
} else {
2018-08-02 15:58:57 +02:00
error = 'invalid propertyString, not a key=value pair and no defaultKey defined' ;
2018-08-01 20:29:06 +02:00
return false ; // break
}
} ) ;
2018-08-02 15:58:57 +02:00
if ( error !== undefined ) {
console . error ( error ) ;
2018-08-01 20:29:06 +02:00
return ;
}
return res ;
} ,
printPropertyString : function ( data , defaultKey ) {
2019-07-10 14:57:38 +02:00
var stringparts = [ ] ,
gotDefaultKeyVal = false ,
defaultKeyVal ;
2018-08-01 20:29:06 +02:00
Ext . Object . each ( data , function ( key , value ) {
2018-08-02 16:00:56 +02:00
if ( defaultKey !== undefined && key === defaultKey ) {
2019-07-10 14:57:38 +02:00
gotDefaultKeyVal = true ;
defaultKeyVal = value ;
2018-08-01 20:29:06 +02:00
} else {
2018-08-02 16:00:56 +02:00
stringparts . push ( key + '=' + value ) ;
2018-08-01 20:29:06 +02:00
}
} ) ;
2019-07-10 14:57:38 +02:00
stringparts = stringparts . sort ( ) ;
if ( gotDefaultKeyVal ) {
stringparts . unshift ( defaultKeyVal ) ;
}
2018-08-01 20:29:06 +02:00
return stringparts . join ( ',' ) ;
} ,
2015-07-03 11:29:11 +02:00
parseQemuNetwork : function ( key , value ) {
if ( ! ( key && value ) ) {
return ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
var match _res ;
if ( ( match _res = p . match ( /^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|vmxnet3|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i ) ) !== null ) {
res . model = match _res [ 1 ] . toLowerCase ( ) ;
if ( match _res [ 3 ] ) {
res . macaddr = match _res [ 3 ] ;
}
} else if ( ( match _res = p . match ( /^bridge=(\S+)$/ ) ) !== null ) {
res . bridge = match _res [ 1 ] ;
} else if ( ( match _res = p . match ( /^rate=(\d+(\.\d+)?)$/ ) ) !== null ) {
res . rate = match _res [ 1 ] ;
} else if ( ( match _res = p . match ( /^tag=(\d+(\.\d+)?)$/ ) ) !== null ) {
2016-04-11 11:44:30 +02:00
res . tag = match _res [ 1 ] ;
2015-07-03 11:29:11 +02:00
} else if ( ( match _res = p . match ( /^firewall=(\d+)$/ ) ) !== null ) {
2016-04-11 11:44:30 +02:00
res . firewall = match _res [ 1 ] ;
2015-07-03 11:29:11 +02:00
} else if ( ( match _res = p . match ( /^link_down=(\d+)$/ ) ) !== null ) {
2016-04-11 11:44:30 +02:00
res . disconnect = match _res [ 1 ] ;
2015-07-03 11:29:11 +02:00
} else if ( ( match _res = p . match ( /^queues=(\d+)$/ ) ) !== null ) {
2016-04-11 11:44:30 +02:00
res . queues = match _res [ 1 ] ;
2016-04-11 11:44:29 +02:00
} else if ( ( match _res = p . match ( /^trunks=(\d+(?:-\d+)?(?:;\d+(?:-\d+)?)*)$/ ) ) !== null ) {
res . trunks = match _res [ 1 ] ;
2015-07-03 11:29:11 +02:00
} else {
errors = true ;
return false ; // break
}
} ) ;
if ( errors || ! res . model ) {
return ;
}
return res ;
} ,
printQemuNetwork : function ( net ) {
var netstr = net . model ;
if ( net . macaddr ) {
netstr += "=" + net . macaddr ;
}
if ( net . bridge ) {
netstr += ",bridge=" + net . bridge ;
if ( net . tag ) {
netstr += ",tag=" + net . tag ;
}
if ( net . firewall ) {
netstr += ",firewall=" + net . firewall ;
}
}
if ( net . rate ) {
netstr += ",rate=" + net . rate ;
}
if ( net . queues ) {
netstr += ",queues=" + net . queues ;
}
if ( net . disconnect ) {
netstr += ",link_down=" + net . disconnect ;
}
2016-04-11 11:44:29 +02:00
if ( net . trunks ) {
netstr += ",trunks=" + net . trunks ;
}
2015-07-03 11:29:11 +02:00
return netstr ;
} ,
parseQemuDrive : function ( key , value ) {
if ( ! ( key && value ) ) {
return ;
}
var res = { } ;
var match _res = key . match ( /^([a-z]+)(\d+)$/ ) ;
if ( ! match _res ) {
return ;
}
res [ 'interface' ] = match _res [ 1 ] ;
res . index = match _res [ 2 ] ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
var match _res = p . match ( /^([a-z_]+)=(\S+)$/ ) ;
if ( ! match _res ) {
if ( ! p . match ( /\=/ ) ) {
res . file = p ;
return ; // continue
}
errors = true ;
return false ; // break
}
var k = match _res [ 1 ] ;
if ( k === 'volume' ) {
k = 'file' ;
}
if ( Ext . isDefined ( res [ k ] ) ) {
errors = true ;
return false ; // break
}
var v = match _res [ 2 ] ;
if ( k === 'cache' && v === 'off' ) {
v = 'none' ;
}
res [ k ] = v ;
} ) ;
if ( errors || ! res . file ) {
return ;
}
return res ;
} ,
printQemuDrive : function ( drive ) {
var drivestr = drive . file ;
Ext . Object . each ( drive , function ( key , value ) {
if ( ! Ext . isDefined ( value ) || key === 'file' ||
key === 'index' || key === 'interface' ) {
return ; // continue
}
drivestr += ',' + key + '=' + value ;
} ) ;
return drivestr ;
} ,
2018-03-15 16:21:33 +01:00
parseIPConfig : function ( key , value ) {
if ( ! ( key && value ) ) {
return ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
var match _res ;
if ( ( match _res = p . match ( /^ip=(\S+)$/ ) ) !== null ) {
res . ip = match _res [ 1 ] ;
} else if ( ( match _res = p . match ( /^gw=(\S+)$/ ) ) !== null ) {
res . gw = match _res [ 1 ] ;
} else if ( ( match _res = p . match ( /^ip6=(\S+)$/ ) ) !== null ) {
res . ip6 = match _res [ 1 ] ;
} else if ( ( match _res = p . match ( /^gw6=(\S+)$/ ) ) !== null ) {
res . gw6 = match _res [ 1 ] ;
} else {
errors = true ;
return false ; // break
}
} ) ;
if ( errors ) {
return ;
}
return res ;
} ,
printIPConfig : function ( cfg ) {
var c = "" ;
var str = "" ;
if ( cfg . ip ) {
str += "ip=" + cfg . ip ;
c = "," ;
}
if ( cfg . gw ) {
str += c + "gw=" + cfg . gw ;
c = "," ;
}
if ( cfg . ip6 ) {
str += c + "ip6=" + cfg . ip6 ;
c = "," ;
}
if ( cfg . gw6 ) {
str += c + "gw6=" + cfg . gw6 ;
c = "," ;
}
return str ;
} ,
2015-07-03 11:29:11 +02:00
parseOpenVZNetIf : function ( value ) {
if ( ! value ) {
return ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ';' ) , function ( item ) {
if ( ! item || item . match ( /^\s*$/ ) ) {
return ; // continue
}
var data = { } ;
Ext . Array . each ( item . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
var match _res = p . match ( /^(ifname|mac|bridge|host_ifname|host_mac|mac_filter)=(\S+)$/ ) ;
if ( ! match _res ) {
errors = true ;
return false ; // break
}
if ( match _res [ 1 ] === 'bridge' ) {
var bridgevlanf = match _res [ 2 ] ;
var bridge _res = bridgevlanf . match ( /^(vmbr(\d+))(v(\d+))?(f)?$/ ) ;
if ( ! bridge _res ) {
errors = true ;
return false ; // break
}
2016-04-29 12:06:27 +02:00
data . bridge = bridge _res [ 1 ] ;
data . tag = bridge _res [ 4 ] ;
/*jslint confusion: true*/
data . firewall = bridge _res [ 5 ] ? 1 : 0 ;
/*jslint confusion: false*/
2015-07-03 11:29:11 +02:00
} else {
data [ match _res [ 1 ] ] = match _res [ 2 ] ;
}
} ) ;
if ( errors || ! data . ifname ) {
errors = true ;
return false ; // break
}
data . raw = item ;
res [ data . ifname ] = data ;
} ) ;
return errors ? undefined : res ;
} ,
printOpenVZNetIf : function ( netif ) {
var netarray = [ ] ;
Ext . Object . each ( netif , function ( iface , data ) {
var tmparray = [ ] ;
Ext . Array . each ( [ 'ifname' , 'mac' , 'bridge' , 'host_ifname' , 'host_mac' , 'mac_filter' , 'tag' , 'firewall' ] , function ( key ) {
var value = data [ key ] ;
if ( key === 'bridge' ) {
2016-04-29 12:06:27 +02:00
if ( data . tag ) {
value = value + 'v' + data . tag ;
2015-07-03 11:29:11 +02:00
}
2016-04-29 12:06:27 +02:00
if ( data . firewall ) {
2015-07-03 11:29:11 +02:00
value = value + 'f' ;
}
}
if ( value ) {
tmparray . push ( key + '=' + value ) ;
}
} ) ;
netarray . push ( tmparray . join ( ',' ) ) ;
} ) ;
return netarray . join ( ';' ) ;
} ,
parseLxcNetwork : function ( value ) {
if ( ! value ) {
return ;
}
var data = { } ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
2019-04-04 16:11:28 +02:00
var match _res = p . match ( /^(bridge|hwaddr|mtu|name|ip|ip6|gw|gw6|tag|rate)=(\S+)$/ ) ;
if ( match _res ) {
data [ match _res [ 1 ] ] = match _res [ 2 ] ;
} else if ( ( match _res = p . match ( /^firewall=(\d+)$/ ) ) !== null ) {
2019-04-04 16:59:04 +02:00
data . firewall = PVE . Parser . parseBoolean ( match _res [ 1 ] ) ;
2019-04-04 16:11:28 +02:00
} else {
2015-07-03 11:29:11 +02:00
// todo: simply ignore errors ?
return ; // continue
}
} ) ;
return data ;
} ,
printLxcNetwork : function ( data ) {
var tmparray = [ ] ;
Ext . Array . each ( [ 'bridge' , 'hwaddr' , 'mtu' , 'name' , 'ip' ,
'gw' , 'ip6' , 'gw6' , 'firewall' , 'tag' ] , function ( key ) {
var value = data [ key ] ;
if ( value ) {
tmparray . push ( key + '=' + value ) ;
}
} ) ;
2016-04-22 09:14:09 +02:00
2016-04-29 12:06:27 +02:00
/*jslint confusion: true*/
2016-04-22 10:13:31 +02:00
if ( data . rate > 0 ) {
2016-04-22 09:14:09 +02:00
tmparray . push ( 'rate=' + data . rate ) ;
}
2016-04-29 12:06:27 +02:00
/*jslint confusion: false*/
2015-07-03 11:29:11 +02:00
return tmparray . join ( ',' ) ;
} ,
2016-03-09 15:57:15 +01:00
parseLxcMountPoint : function ( value ) {
if ( ! value ) {
return ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
2018-08-22 10:17:17 +02:00
var match _res = p . match ( /^([a-z_]+)=(.+)$/ ) ;
2016-03-09 15:57:15 +01:00
if ( ! match _res ) {
if ( ! p . match ( /\=/ ) ) {
res . file = p ;
return ; // continue
}
errors = true ;
return false ; // break
}
var k = match _res [ 1 ] ;
if ( k === 'volume' ) {
k = 'file' ;
}
if ( Ext . isDefined ( res [ k ] ) ) {
errors = true ;
return false ; // break
}
var v = match _res [ 2 ] ;
res [ k ] = v ;
} ) ;
if ( errors || ! res . file ) {
return ;
}
2016-03-17 14:22:22 +01:00
var m = res . file . match ( /^([a-z][a-z0-9\-\_\.]*[a-z0-9]):/i ) ;
2016-03-09 15:57:15 +01:00
if ( m ) {
res . storage = m [ 1 ] ;
res . type = 'volume' ;
} else if ( res . file . match ( /^\/dev\// ) ) {
res . type = 'device' ;
} else {
res . type = 'bind' ;
}
return res ;
} ,
printLxcMountPoint : function ( mp ) {
var drivestr = mp . file ;
Ext . Object . each ( mp , function ( key , value ) {
if ( ! Ext . isDefined ( value ) || key === 'file' ||
key === 'type' || key === 'storage' ) {
return ; // continue
}
drivestr += ',' + key + '=' + value ;
} ) ;
return drivestr ;
} ,
2015-07-03 11:29:11 +02:00
parseStartup : function ( value ) {
if ( value === undefined ) {
return ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
var match _res ;
if ( ( match _res = p . match ( /^(order)?=(\d+)$/ ) ) !== null ) {
res . order = match _res [ 2 ] ;
} else if ( ( match _res = p . match ( /^up=(\d+)$/ ) ) !== null ) {
res . up = match _res [ 1 ] ;
} else if ( ( match _res = p . match ( /^down=(\d+)$/ ) ) !== null ) {
res . down = match _res [ 1 ] ;
} else {
errors = true ;
return false ; // break
}
} ) ;
if ( errors ) {
return ;
}
return res ;
} ,
printStartup : function ( startup ) {
var arr = [ ] ;
if ( startup . order !== undefined && startup . order !== '' ) {
arr . push ( 'order=' + startup . order ) ;
}
if ( startup . up !== undefined && startup . up !== '' ) {
arr . push ( 'up=' + startup . up ) ;
}
if ( startup . down !== undefined && startup . down !== '' ) {
arr . push ( 'down=' + startup . down ) ;
}
return arr . join ( ',' ) ;
} ,
parseQemuSmbios1 : function ( value ) {
2019-06-11 15:31:12 +02:00
var res = value . split ( ',' ) . reduce ( function ( accumulator , currentValue ) {
var splitted = currentValue . split ( new RegExp ( "=(.+)" ) ) ;
accumulator [ splitted [ 0 ] ] = splitted [ 1 ] ;
return accumulator ;
} , { } ) ;
if ( PVE . Parser . parseBoolean ( res . base64 , false ) ) {
Ext . Object . each ( res , function ( key , value ) {
if ( key === 'uuid' ) { return ; }
res [ key ] = Ext . util . Base64 . decode ( value ) ;
} ) ;
}
2015-07-03 11:29:11 +02:00
return res ;
} ,
printQemuSmbios1 : function ( data ) {
var datastr = '' ;
2019-06-11 15:31:12 +02:00
var base64 = false ;
2015-07-03 11:29:11 +02:00
Ext . Object . each ( data , function ( key , value ) {
2016-04-29 12:06:26 +02:00
if ( value === '' ) { return ; }
2019-06-11 15:31:12 +02:00
if ( key === 'uuid' ) {
datastr += ( datastr !== '' ? ',' : '' ) + key + '=' + value ;
} else {
// values should be base64 encoded from now on, mark config strings correspondingly
if ( ! base64 ) {
base64 = true ;
datastr += ( datastr !== '' ? ',' : '' ) + 'base64=1' ;
}
datastr += ( datastr !== '' ? ',' : '' ) + key + '=' + Ext . util . Base64 . encode ( value ) ;
}
2015-07-03 11:29:11 +02:00
} ) ;
return datastr ;
} ,
parseTfaConfig : function ( value ) {
var res = { } ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
2016-04-29 12:06:27 +02:00
var kva = p . split ( '=' , 2 ) ;
2015-07-03 11:29:11 +02:00
res [ kva [ 0 ] ] = kva [ 1 ] ;
} ) ;
return res ;
2016-03-09 15:57:15 +01:00
} ,
2019-04-11 11:31:59 +02:00
parseTfaType : function ( value ) {
2019-04-16 07:46:59 +00:00
/*jslint confusion: true*/
2019-04-11 11:31:59 +02:00
var match ;
if ( ! value || ! value . length ) {
return undefined ;
} else if ( value === 'x!oath' ) {
return 'totp' ;
2019-04-16 07:46:59 +00:00
} else if ( ! ! ( match = value . match ( /^x!(.+)$/ ) ) ) {
2019-04-11 11:31:59 +02:00
return match [ 1 ] ;
} else {
return 1 ;
}
} ,
2016-03-09 15:57:15 +01:00
parseQemuCpu : function ( value ) {
if ( ! value ) {
return { } ;
}
var res = { } ;
var errors = false ;
Ext . Array . each ( value . split ( ',' ) , function ( p ) {
if ( ! p || p . match ( /^\s*$/ ) ) {
return ; // continue
}
2015-07-03 11:29:11 +02:00
2016-04-29 12:06:27 +02:00
if ( ! p . match ( /\=/ ) ) {
if ( Ext . isDefined ( res . cpu ) ) {
2016-03-09 15:57:15 +01:00
errors = true ;
return false ; // break
}
res . cputype = p ;
return ; // continue
}
var match _res = p . match ( /^([a-z_]+)=(\S+)$/ ) ;
if ( ! match _res ) {
errors = true ;
return false ; // break
}
var k = match _res [ 1 ] ;
if ( Ext . isDefined ( res [ k ] ) ) {
errors = true ;
return false ; // break
}
res [ k ] = match _res [ 2 ] ;
} ) ;
if ( errors || ! res . cputype ) {
return ;
}
return res ;
} ,
printQemuCpu : function ( cpu ) {
var cpustr = cpu . cputype ;
var optstr = '' ;
Ext . Object . each ( cpu , function ( key , value ) {
if ( ! Ext . isDefined ( value ) || key === 'cputype' ) {
return ; // continue
}
optstr += ',' + key + '=' + value ;
} ) ;
if ( ! cpustr ) {
2016-04-29 12:06:26 +02:00
if ( optstr ) {
2016-03-09 15:57:15 +01:00
return 'kvm64' + optstr ;
2016-04-29 12:06:26 +02:00
}
2016-03-09 15:57:15 +01:00
return ;
}
return cpustr + optstr ;
2016-08-10 12:13:19 +02:00
} ,
parseSSHKey : function ( key ) {
// |--- options can have quotes--| type key comment
var keyre = /^(?:((?:[^\s"]|\"(?:\\.|[^"\\])*")+)\s+)?(\S+)\s+(\S+)(?:\s+(.*))?$/ ;
var typere = /^(?:ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)$/ ;
var m = key . match ( keyre ) ;
if ( ! m ) {
return null ;
}
if ( m . length < 3 || ! m [ 2 ] ) { // [2] is always either type or key
return null ;
}
if ( m [ 1 ] && m [ 1 ] . match ( typere ) ) {
return {
type : m [ 1 ] ,
key : m [ 2 ] ,
comment : m [ 3 ]
} ;
}
if ( m [ 2 ] . match ( typere ) ) {
return {
options : m [ 1 ] ,
type : m [ 2 ] ,
key : m [ 3 ] ,
comment : m [ 4 ]
} ;
}
return null ;
2016-04-29 12:06:28 +02:00
}
2015-07-03 11:29:11 +02:00
} } ) ;