Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
OpnSense
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kulya
OpnSense
Commits
f763963c
Commit
f763963c
authored
Feb 01, 2016
by
Ad Schellevis
Committed by
Franco Fichtner
Feb 17, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(configd) code style cleanups
(cherry picked from commit
9c84f2b4
)
parent
52093041
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
93 additions
and
67 deletions
+93
-67
__init__.py
src/opnsense/service/modules/__init__.py
+5
-0
template_helpers.py
src/opnsense/service/modules/addons/template_helpers.py
+3
-1
config.py
src/opnsense/service/modules/config.py
+10
-9
daemonize.py
src/opnsense/service/modules/daemonize.py
+1
-0
ph_inline_actions.py
src/opnsense/service/modules/ph_inline_actions.py
+2
-2
processhandler.py
src/opnsense/service/modules/processhandler.py
+54
-39
template.py
src/opnsense/service/modules/template.py
+18
-16
No files found.
src/opnsense/service/modules/__init__.py
View file @
f763963c
...
@@ -24,12 +24,17 @@
...
@@ -24,12 +24,17 @@
POSSIBILITY OF SUCH DAMAGE.
POSSIBILITY OF SUCH DAMAGE.
"""
"""
def
singleton
(
cls
,
*
args
,
**
kwargs
):
def
singleton
(
cls
,
*
args
,
**
kwargs
):
""" singleton pattern, use ad decorator
""" singleton pattern, use ad decorator
:param cls:
"""
"""
instances
=
{}
instances
=
{}
# noinspection PyShadowingNames
def
getinstance
(
*
args
,
**
kwargs
):
def
getinstance
(
*
args
,
**
kwargs
):
if
cls
not
in
instances
:
if
cls
not
in
instances
:
instances
[
cls
]
=
cls
(
*
args
,
**
kwargs
)
instances
[
cls
]
=
cls
(
*
args
,
**
kwargs
)
return
instances
[
cls
]
return
instances
[
cls
]
return
getinstance
return
getinstance
src/opnsense/service/modules/addons/template_helpers.py
View file @
f763963c
...
@@ -30,6 +30,8 @@
...
@@ -30,6 +30,8 @@
from
operator
import
itemgetter
from
operator
import
itemgetter
# noinspection PyPep8Naming
class
Helpers
(
object
):
class
Helpers
(
object
):
def
__init__
(
self
,
template_in_data
):
def
__init__
(
self
,
template_in_data
):
""" initialize template helpers
""" initialize template helpers
...
@@ -82,7 +84,7 @@ class Helpers(object):
...
@@ -82,7 +84,7 @@ class Helpers(object):
return
result
return
result
else
:
else
:
# resort list by tag
# resort list by tag
return
sorted
(
result
,
key
=
itemgetter
(
sortBy
))
return
sorted
(
result
,
key
=
itemgetter
(
sortBy
))
def
getUUIDtag
(
self
,
uuid
):
def
getUUIDtag
(
self
,
uuid
):
""" retrieve tag name of registered uuid, returns __not_found__ if none available
""" retrieve tag name of registered uuid, returns __not_found__ if none available
...
...
src/opnsense/service/modules/config.py
View file @
f763963c
...
@@ -28,14 +28,14 @@
...
@@ -28,14 +28,14 @@
package : configd
package : configd
function: config handler
function: config handler
"""
"""
__author__
=
'Ad Schellevis'
import
os
import
os
import
stat
import
stat
import
collections
import
collections
import
copy
import
copy
import
xml.etree.cElementTree
as
ElementTree
import
xml.etree.cElementTree
as
ElementTree
__author__
=
'Ad Schellevis'
class
Config
(
object
):
class
Config
(
object
):
def
__init__
(
self
,
filename
):
def
__init__
(
self
,
filename
):
...
@@ -62,14 +62,14 @@ class Config(object):
...
@@ -62,14 +62,14 @@ class Config(object):
self
.
_config_data
[
'__uuid_tags__'
]
=
self
.
__uuid_tags
self
.
_config_data
[
'__uuid_tags__'
]
=
self
.
__uuid_tags
self
.
_file_mod
=
mod_time
self
.
_file_mod
=
mod_time
def
_traverse
(
self
,
xml
N
ode
):
def
_traverse
(
self
,
xml
_n
ode
):
""" traverse xml node and return ordered dictionary structure
""" traverse xml node and return ordered dictionary structure
:param xml
N
ode: ElementTree node
:param xml
_n
ode: ElementTree node
:return: collections.OrderedDict
:return: collections.OrderedDict
"""
"""
this_item
=
collections
.
OrderedDict
()
this_item
=
collections
.
OrderedDict
()
if
len
(
list
(
xml
N
ode
))
>
0
:
if
len
(
list
(
xml
_n
ode
))
>
0
:
for
item
in
list
(
xml
N
ode
):
for
item
in
list
(
xml
_n
ode
):
item_content
=
self
.
_traverse
(
item
)
item_content
=
self
.
_traverse
(
item
)
if
'uuid'
in
item
.
attrib
:
if
'uuid'
in
item
.
attrib
:
self
.
__uuid_data
[
item
.
attrib
[
'uuid'
]]
=
item_content
self
.
__uuid_data
[
item
.
attrib
[
'uuid'
]]
=
item_content
...
@@ -88,7 +88,7 @@ class Config(object):
...
@@ -88,7 +88,7 @@ class Config(object):
this_item
[
item
.
tag
]
=
self
.
_traverse
(
item
)
this_item
[
item
.
tag
]
=
self
.
_traverse
(
item
)
else
:
else
:
# last node, return text
# last node, return text
return
xml
N
ode
.
text
return
xml
_n
ode
.
text
return
this_item
return
this_item
...
@@ -98,14 +98,15 @@ class Config(object):
...
@@ -98,14 +98,15 @@ class Config(object):
@param elem: cElementTree
@param elem: cElementTree
@param level: Currentlevel
@param level: Currentlevel
"""
"""
i
=
"
\n
"
+
level
*
" "
i
=
"
\n
"
+
level
*
" "
if
len
(
elem
):
if
len
(
elem
):
if
not
elem
.
text
or
not
elem
.
text
.
strip
():
if
not
elem
.
text
or
not
elem
.
text
.
strip
():
elem
.
text
=
i
+
" "
elem
.
text
=
i
+
" "
for
e
in
elem
:
for
e
in
elem
:
self
.
indent
(
e
,
level
+
1
)
self
.
indent
(
e
,
level
+
1
)
if
not
e
.
tail
or
not
e
.
tail
.
strip
():
if
not
e
.
tail
or
not
e
.
tail
.
strip
():
e
.
tail
=
i
+
" "
e
.
tail
=
i
+
" "
# noinspection PyUnboundLocalVariable
if
not
e
.
tail
or
not
e
.
tail
.
strip
():
if
not
e
.
tail
or
not
e
.
tail
.
strip
():
e
.
tail
=
i
e
.
tail
=
i
else
:
else
:
...
...
src/opnsense/service/modules/daemonize.py
View file @
f763963c
...
@@ -58,6 +58,7 @@ class Daemonize(object):
...
@@ -58,6 +58,7 @@ class Daemonize(object):
def
sigterm
(
self
,
signum
,
frame
):
def
sigterm
(
self
,
signum
,
frame
):
"""
"""
These actions will be done after SIGTERM.
These actions will be done after SIGTERM.
:param frame:
"""
"""
self
.
logger
.
warn
(
"Caught signal
%
s. Stopping daemon."
%
signum
)
self
.
logger
.
warn
(
"Caught signal
%
s. Stopping daemon."
%
signum
)
os
.
remove
(
self
.
pid
)
os
.
remove
(
self
.
pid
)
...
...
src/opnsense/service/modules/ph_inline_actions.py
View file @
f763963c
...
@@ -48,7 +48,7 @@ def execute(action, parameters):
...
@@ -48,7 +48,7 @@ def execute(action, parameters):
# generate template
# generate template
tmpl
=
template
.
Template
(
action
.
root_dir
)
tmpl
=
template
.
Template
(
action
.
root_dir
)
conf
=
config
.
Config
(
action
.
config
)
conf
=
config
.
Config
(
action
.
config
)
tmpl
.
set
C
onfig
(
conf
.
get
())
tmpl
.
set
_c
onfig
(
conf
.
get
())
filenames
=
tmpl
.
generate
(
parameters
)
filenames
=
tmpl
.
generate
(
parameters
)
del
conf
del
conf
...
@@ -78,7 +78,7 @@ def execute(action, parameters):
...
@@ -78,7 +78,7 @@ def execute(action, parameters):
# list all available configd actions
# list all available configd actions
from
processhandler
import
ActionHandler
from
processhandler
import
ActionHandler
act_handler
=
ActionHandler
()
act_handler
=
ActionHandler
()
actions
=
act_handler
.
list
A
ctions
([
'message'
,
'description'
])
actions
=
act_handler
.
list
_a
ctions
([
'message'
,
'description'
])
if
unicode
(
parameters
)
.
lower
()
==
'json'
:
if
unicode
(
parameters
)
.
lower
()
==
'json'
:
import
json
import
json
...
...
src/opnsense/service/modules/processhandler.py
View file @
f763963c
...
@@ -28,8 +28,6 @@
...
@@ -28,8 +28,6 @@
function: unix domain socket process worker process
function: unix domain socket process worker process
"""
"""
__author__
=
'Ad Schellevis'
import
os
import
os
import
subprocess
import
subprocess
import
socket
import
socket
...
@@ -45,6 +43,8 @@ import tempfile
...
@@ -45,6 +43,8 @@ import tempfile
import
ph_inline_actions
import
ph_inline_actions
from
modules
import
singleton
from
modules
import
singleton
__author__
=
'Ad Schellevis'
class
Handler
(
object
):
class
Handler
(
object
):
""" Main handler class, opens unix domain socket and starts listening
""" Main handler class, opens unix domain socket and starts listening
...
@@ -57,7 +57,8 @@ class Handler(object):
...
@@ -57,7 +57,8 @@ class Handler(object):
-> execute ActionHandler command using Action objects
-> execute ActionHandler command using Action objects
<- send back result string
<- send back result string
"""
"""
def
__init__
(
self
,
socket_filename
,
config_path
,
config_environment
=
{},
simulation_mode
=
False
):
def
__init__
(
self
,
socket_filename
,
config_path
,
config_environment
=
None
,
simulation_mode
=
False
):
""" Constructor
""" Constructor
:param socket_filename: filename of unix domain socket to use
:param socket_filename: filename of unix domain socket to use
...
@@ -65,6 +66,8 @@ class Handler(object):
...
@@ -65,6 +66,8 @@ class Handler(object):
:param simulation_mode: emulation mode, do not start actual (script) commands
:param simulation_mode: emulation mode, do not start actual (script) commands
:return: object
:return: object
"""
"""
if
config_environment
is
None
:
config_environment
=
{}
self
.
socket_filename
=
socket_filename
self
.
socket_filename
=
socket_filename
self
.
config_path
=
config_path
self
.
config_path
=
config_path
self
.
simulation_mode
=
simulation_mode
self
.
simulation_mode
=
simulation_mode
...
@@ -77,9 +80,10 @@ class Handler(object):
...
@@ -77,9 +80,10 @@ class Handler(object):
:return:
:return:
"""
"""
while
True
:
while
True
:
# noinspection PyBroadException
try
:
try
:
# open action handler
# open action handler
act
H
andler
=
ActionHandler
(
config_path
=
self
.
config_path
,
act
_h
andler
=
ActionHandler
(
config_path
=
self
.
config_path
,
config_environment
=
self
.
config_environment
)
config_environment
=
self
.
config_environment
)
# remove previous socket ( if exists )
# remove previous socket ( if exists )
...
@@ -99,7 +103,7 @@ class Handler(object):
...
@@ -99,7 +103,7 @@ class Handler(object):
# spawn a client connection
# spawn a client connection
cmd_thread
=
HandlerClient
(
connection
=
connection
,
cmd_thread
=
HandlerClient
(
connection
=
connection
,
client_address
=
client_address
,
client_address
=
client_address
,
action_handler
=
act
H
andler
,
action_handler
=
act
_h
andler
,
simulation_mode
=
self
.
simulation_mode
)
simulation_mode
=
self
.
simulation_mode
)
if
self
.
single_threaded
:
if
self
.
single_threaded
:
# run single threaded
# run single threaded
...
@@ -120,7 +124,7 @@ class Handler(object):
...
@@ -120,7 +124,7 @@ class Handler(object):
# cleanup on exit, remove socket
# cleanup on exit, remove socket
os
.
remove
(
self
.
socket_filename
)
os
.
remove
(
self
.
socket_filename
)
return
return
except
:
except
Exception
:
# something went wrong... send traceback to syslog, restart listener (wait for a short time)
# something went wrong... send traceback to syslog, restart listener (wait for a short time)
print
(
traceback
.
format_exc
())
print
(
traceback
.
format_exc
())
syslog
.
syslog
(
syslog
.
LOG_ERR
,
'Handler died on
%
s'
%
traceback
.
format_exc
())
syslog
.
syslog
(
syslog
.
LOG_ERR
,
'Handler died on
%
s'
%
traceback
.
format_exc
())
...
@@ -130,6 +134,7 @@ class Handler(object):
...
@@ -130,6 +134,7 @@ class Handler(object):
class
HandlerClient
(
threading
.
Thread
):
class
HandlerClient
(
threading
.
Thread
):
""" Handle commands via specified socket connection
""" Handle commands via specified socket connection
"""
"""
def
__init__
(
self
,
connection
,
client_address
,
action_handler
,
simulation_mode
=
False
):
def
__init__
(
self
,
connection
,
client_address
,
action_handler
,
simulation_mode
=
False
):
"""
"""
:param connection: socket connection object
:param connection: socket connection object
...
@@ -155,6 +160,7 @@ class HandlerClient(threading.Thread):
...
@@ -155,6 +160,7 @@ class HandlerClient(threading.Thread):
exec_action
=
''
exec_action
=
''
exec_params
=
''
exec_params
=
''
exec_in_background
=
False
exec_in_background
=
False
# noinspection PyBroadException
try
:
try
:
# receive command, maximum data length is 4k... longer messages will be truncated
# receive command, maximum data length is 4k... longer messages will be truncated
data
=
self
.
connection
.
recv
(
4096
)
data
=
self
.
connection
.
recv
(
4096
)
...
@@ -186,7 +192,7 @@ class HandlerClient(threading.Thread):
...
@@ -186,7 +192,7 @@ class HandlerClient(threading.Thread):
# execute requested action
# execute requested action
if
self
.
simulation_mode
:
if
self
.
simulation_mode
:
self
.
action_handler
.
show
A
ction
(
exec_command
,
exec_action
,
exec_params
,
self
.
message_uuid
)
self
.
action_handler
.
show
_a
ction
(
exec_command
,
exec_action
,
exec_params
,
self
.
message_uuid
)
result
=
'OK'
result
=
'OK'
else
:
else
:
result
=
self
.
action_handler
.
execute
(
exec_command
,
exec_action
,
exec_params
,
self
.
message_uuid
)
result
=
self
.
action_handler
.
execute
(
exec_command
,
exec_action
,
exec_params
,
self
.
message_uuid
)
...
@@ -207,23 +213,28 @@ class HandlerClient(threading.Thread):
...
@@ -207,23 +213,28 @@ class HandlerClient(threading.Thread):
except
SystemExit
:
except
SystemExit
:
# ignore system exit related errors
# ignore system exit related errors
pass
pass
except
:
except
Exception
:
print
(
traceback
.
format_exc
())
print
(
traceback
.
format_exc
())
syslog
.
syslog
(
syslog
.
LOG_ERR
,
syslog
.
syslog
(
syslog
.
LOG_ERR
,
'unable to sendback response [
%
s] for [
%
s][
%
s][
%
s] {
%
s}, message was
%
s'
%
(
result
,
'unable to sendback response [
%
s] for [
%
s][
%
s][
%
s] {
%
s}, message was
%
s'
%
(
result
,
exec_command
,
exec_command
,
exec_action
,
exec_action
,
exec_params
,
exec_params
,
self
.
message_uuid
,
self
.
message_uuid
,
traceback
.
format_exc
()))
traceback
.
format_exc
()
)
)
finally
:
finally
:
if
not
exec_in_background
:
if
not
exec_in_background
:
self
.
connection
.
close
()
self
.
connection
.
close
()
@
singleton
@
singleton
class
ActionHandler
(
object
):
class
ActionHandler
(
object
):
""" Start/stop services and functions using configuration data defined in conf/actions_<topic>.conf
""" Start/stop services and functions using configuration data defined in conf/actions_<topic>.conf
"""
"""
def
__init__
(
self
,
config_path
=
None
,
config_environment
=
None
):
def
__init__
(
self
,
config_path
=
None
,
config_environment
=
None
):
""" Initialize action handler to start system functions
""" Initialize action handler to start system functions
...
@@ -238,6 +249,7 @@ class ActionHandler(object):
...
@@ -238,6 +249,7 @@ class ActionHandler(object):
# try to load data on initial start
# try to load data on initial start
if
not
hasattr
(
self
,
'action_map'
):
if
not
hasattr
(
self
,
'action_map'
):
self
.
action_map
=
{}
self
.
load_config
()
self
.
load_config
()
def
load_config
(
self
):
def
load_config
(
self
):
...
@@ -245,8 +257,6 @@ class ActionHandler(object):
...
@@ -245,8 +257,6 @@ class ActionHandler(object):
:return: None
:return: None
"""
"""
self
.
action_map
=
{}
for
config_filename
in
glob
.
glob
(
'
%
s/actions_*.conf'
%
self
.
config_path
)
\
for
config_filename
in
glob
.
glob
(
'
%
s/actions_*.conf'
%
self
.
config_path
)
\
+
glob
.
glob
(
'
%
s/actions.d/actions_*.conf'
%
self
.
config_path
):
+
glob
.
glob
(
'
%
s/actions.d/actions_*.conf'
%
self
.
config_path
):
# this topic's name (service, filter, template, etc)
# this topic's name (service, filter, template, etc)
...
@@ -260,7 +270,7 @@ class ActionHandler(object):
...
@@ -260,7 +270,7 @@ class ActionHandler(object):
cnf
.
read
(
config_filename
)
cnf
.
read
(
config_filename
)
for
section
in
cnf
.
sections
():
for
section
in
cnf
.
sections
():
# map configuration data on object
# map configuration data on object
action_obj
=
Action
(
config_environment
=
self
.
config_environment
)
action_obj
=
Action
(
config_environment
=
self
.
config_environment
)
for
act_prop
in
cnf
.
items
(
section
):
for
act_prop
in
cnf
.
items
(
section
):
setattr
(
action_obj
,
act_prop
[
0
],
act_prop
[
1
])
setattr
(
action_obj
,
act_prop
[
0
],
act_prop
[
1
])
...
@@ -274,10 +284,13 @@ class ActionHandler(object):
...
@@ -274,10 +284,13 @@ class ActionHandler(object):
for
alias
in
section
.
split
(
'|'
):
for
alias
in
section
.
split
(
'|'
):
self
.
action_map
[
topic_name
][
alias
]
=
action_obj
self
.
action_map
[
topic_name
][
alias
]
=
action_obj
def
list
Actions
(
self
,
attributes
=
[]
):
def
list
_actions
(
self
,
attributes
=
None
):
""" list all available actions
""" list all available actions
:param attributes:
:return: dict
:return: dict
"""
"""
if
attributes
is
None
:
attributes
=
[]
result
=
{}
result
=
{}
for
command
in
self
.
action_map
:
for
command
in
self
.
action_map
:
for
action
in
self
.
action_map
[
command
]:
for
action
in
self
.
action_map
[
command
]:
...
@@ -285,7 +298,7 @@ class ActionHandler(object):
...
@@ -285,7 +298,7 @@ class ActionHandler(object):
# parse second level actions
# parse second level actions
# TODO: nesting actions may be better to solve recursive in here and in load_config part
# TODO: nesting actions may be better to solve recursive in here and in load_config part
for
subAction
in
self
.
action_map
[
command
][
action
]:
for
subAction
in
self
.
action_map
[
command
][
action
]:
cmd
=
'
%
s
%
s
%
s'
%
(
command
,
action
,
subAction
)
cmd
=
'
%
s
%
s
%
s'
%
(
command
,
action
,
subAction
)
result
[
cmd
]
=
{}
result
[
cmd
]
=
{}
for
actAttr
in
attributes
:
for
actAttr
in
attributes
:
if
hasattr
(
self
.
action_map
[
command
][
action
][
subAction
],
actAttr
):
if
hasattr
(
self
.
action_map
[
command
][
action
][
subAction
],
actAttr
):
...
@@ -293,7 +306,7 @@ class ActionHandler(object):
...
@@ -293,7 +306,7 @@ class ActionHandler(object):
else
:
else
:
result
[
cmd
][
actAttr
]
=
''
result
[
cmd
][
actAttr
]
=
''
else
:
else
:
cmd
=
'
%
s
%
s'
%
(
command
,
action
)
cmd
=
'
%
s
%
s'
%
(
command
,
action
)
result
[
cmd
]
=
{}
result
[
cmd
]
=
{}
for
actAttr
in
attributes
:
for
actAttr
in
attributes
:
if
hasattr
(
self
.
action_map
[
command
][
action
],
actAttr
):
if
hasattr
(
self
.
action_map
[
command
][
action
],
actAttr
):
...
@@ -303,7 +316,7 @@ class ActionHandler(object):
...
@@ -303,7 +316,7 @@ class ActionHandler(object):
return
result
return
result
def
find
A
ction
(
self
,
command
,
action
,
parameters
):
def
find
_a
ction
(
self
,
command
,
action
,
parameters
):
""" find action object
""" find action object
:param command: command/topic for example interface
:param command: command/topic for example interface
...
@@ -320,7 +333,7 @@ class ActionHandler(object):
...
@@ -320,7 +333,7 @@ class ActionHandler(object):
# 3 level action ( "interface linkup start" for example )
# 3 level action ( "interface linkup start" for example )
if
isinstance
(
self
.
action_map
[
command
][
action
][
parameters
[
0
]],
Action
):
if
isinstance
(
self
.
action_map
[
command
][
action
][
parameters
[
0
]],
Action
):
action_obj
=
self
.
action_map
[
command
][
action
][
parameters
[
0
]]
action_obj
=
self
.
action_map
[
command
][
action
][
parameters
[
0
]]
action_obj
.
set
ParameterStartP
os
(
1
)
action_obj
.
set
_parameter_start_p
os
(
1
)
elif
isinstance
(
self
.
action_map
[
command
][
action
],
Action
):
elif
isinstance
(
self
.
action_map
[
command
][
action
],
Action
):
action_obj
=
self
.
action_map
[
command
][
action
]
action_obj
=
self
.
action_map
[
command
][
action
]
...
@@ -336,17 +349,17 @@ class ActionHandler(object):
...
@@ -336,17 +349,17 @@ class ActionHandler(object):
:return: OK on success, else error code
:return: OK on success, else error code
"""
"""
action_params
=
[]
action_params
=
[]
action_obj
=
self
.
find
A
ction
(
command
,
action
,
parameters
)
action_obj
=
self
.
find
_a
ction
(
command
,
action
,
parameters
)
if
action_obj
is
not
None
:
if
action_obj
is
not
None
:
if
parameters
is
not
None
and
len
(
parameters
)
>
action_obj
.
get
ParameterStartP
os
():
if
parameters
is
not
None
and
len
(
parameters
)
>
action_obj
.
get
_parameter_start_p
os
():
action_params
=
parameters
[
action_obj
.
get
ParameterStartP
os
():]
action_params
=
parameters
[
action_obj
.
get
_parameter_start_p
os
():]
return
'
%
s
\n
'
%
action_obj
.
execute
(
action_params
,
message_uuid
)
return
'
%
s
\n
'
%
action_obj
.
execute
(
action_params
,
message_uuid
)
return
'Action not found
\n
'
return
'Action not found
\n
'
def
show
A
ction
(
self
,
command
,
action
,
parameters
,
message_uuid
):
def
show
_a
ction
(
self
,
command
,
action
,
parameters
,
message_uuid
):
""" debug/simulation mode: show action information
""" debug/simulation mode: show action information
:param command: command/topic for example interface
:param command: command/topic for example interface
:param action: action to run ( for example linkup )
:param action: action to run ( for example linkup )
...
@@ -354,10 +367,10 @@ class ActionHandler(object):
...
@@ -354,10 +367,10 @@ class ActionHandler(object):
:param message_uuid: message unique id
:param message_uuid: message unique id
:return: None
:return: None
"""
"""
action_obj
=
self
.
find
A
ction
(
command
,
action
,
parameters
)
action_obj
=
self
.
find
_a
ction
(
command
,
action
,
parameters
)
print
(
'---------------------------------------------------------------------'
)
print
(
'---------------------------------------------------------------------'
)
print
(
'execute
%
s.
%
s with parameters :
%
s '
%
(
command
,
action
,
parameters
))
print
(
'execute
%
s.
%
s with parameters :
%
s '
%
(
command
,
action
,
parameters
))
print
(
'action object
%
s (
%
s)
'
%
(
action_obj
,
action_obj
.
comman
d
))
print
(
'action object
%
s (
%
s)
%
s'
%
(
action_obj
,
action_obj
.
command
,
message_uui
d
))
print
(
'---------------------------------------------------------------------'
)
print
(
'---------------------------------------------------------------------'
)
...
@@ -365,6 +378,7 @@ class Action(object):
...
@@ -365,6 +378,7 @@ class Action(object):
""" Action class, handles actual (system) calls.
""" Action class, handles actual (system) calls.
set command, parameters (template) type and log message
set command, parameters (template) type and log message
"""
"""
def
__init__
(
self
,
config_environment
):
def
__init__
(
self
,
config_environment
):
""" setup default properties
""" setup default properties
:param config_environment: environment to use
:param config_environment: environment to use
...
@@ -377,7 +391,7 @@ class Action(object):
...
@@ -377,7 +391,7 @@ class Action(object):
self
.
message
=
None
self
.
message
=
None
self
.
_parameter_start_pos
=
0
self
.
_parameter_start_pos
=
0
def
set
ParameterStartP
os
(
self
,
pos
):
def
set
_parameter_start_p
os
(
self
,
pos
):
"""
"""
:param pos: start position of parameter list
:param pos: start position of parameter list
...
@@ -385,7 +399,7 @@ class Action(object):
...
@@ -385,7 +399,7 @@ class Action(object):
"""
"""
self
.
_parameter_start_pos
=
pos
self
.
_parameter_start_pos
=
pos
def
get
ParameterStartP
os
(
self
):
def
get
_parameter_start_p
os
(
self
):
""" getter for _parameter_start_pos
""" getter for _parameter_start_pos
:return: start position of parameter list ( first argument can be part of action to start )
:return: start position of parameter list ( first argument can be part of action to start )
"""
"""
...
@@ -427,18 +441,18 @@ class Action(object):
...
@@ -427,18 +441,18 @@ class Action(object):
# use quotes on parameters to prevent code injection
# use quotes on parameters to prevent code injection
if
script_command
.
count
(
'
%
s'
)
>
len
(
parameters
):
if
script_command
.
count
(
'
%
s'
)
>
len
(
parameters
):
# script command accepts more parameters then given, fill with empty parameters
# script command accepts more parameters then given, fill with empty parameters
for
i
in
range
(
script_command
.
count
(
'
%
s'
)
-
len
(
parameters
)):
for
i
in
range
(
script_command
.
count
(
'
%
s'
)
-
len
(
parameters
)):
parameters
.
append
(
""
)
parameters
.
append
(
""
)
elif
len
(
parameters
)
>
script_command
.
count
(
'
%
s'
):
elif
len
(
parameters
)
>
script_command
.
count
(
'
%
s'
):
# parameters then expected, fail execution
# parameters then expected, fail execution
return
'Parameter mismatch'
return
'Parameter mismatch'
# force escape of shell exploitable characters for all user parameters
# force escape of shell exploitable characters for all user parameters
for
escape_char
in
[
'`'
,
'$'
,
'!'
,
'('
,
')'
,
'|'
]:
for
escape_char
in
[
'`'
,
'$'
,
'!'
,
'('
,
')'
,
'|'
]:
for
i
in
range
(
len
(
parameters
[
0
:
script_command
.
count
(
'
%
s'
)])):
for
i
in
range
(
len
(
parameters
[
0
:
script_command
.
count
(
'
%
s'
)])):
parameters
[
i
]
=
parameters
[
i
]
.
replace
(
escape_char
,
'
\\
%
s'
%
escape_char
)
parameters
[
i
]
=
parameters
[
i
]
.
replace
(
escape_char
,
'
\\
%
s'
%
escape_char
)
script_command
=
script_command
%
tuple
(
map
(
lambda
x
:
'"'
+
x
.
replace
(
'"'
,
'
\\
"'
)
+
'"'
,
script_command
=
script_command
%
tuple
(
map
(
lambda
x
:
'"'
+
x
.
replace
(
'"'
,
'
\\
"'
)
+
'"'
,
parameters
[
0
:
script_command
.
count
(
'
%
s'
)]))
parameters
[
0
:
script_command
.
count
(
'
%
s'
)]))
if
self
.
type
.
lower
()
==
'script'
:
if
self
.
type
.
lower
()
==
'script'
:
# execute script type command
# execute script type command
...
@@ -466,8 +480,9 @@ class Action(object):
...
@@ -466,8 +480,9 @@ class Action(object):
script_output
=
output_stream
.
read
()
script_output
=
output_stream
.
read
()
script_error_output
=
error_stream
.
read
()
script_error_output
=
error_stream
.
read
()
if
len
(
script_error_output
)
>
0
:
if
len
(
script_error_output
)
>
0
:
syslog
.
syslog
(
syslog
.
LOG_ERR
,
'[
%
s] Script action stderr returned "
%
s"'
%
(
message_uuid
,
syslog
.
syslog
(
syslog
.
LOG_ERR
,
script_error_output
.
strip
()[:
255
])
'[
%
s] Script action stderr returned "
%
s"'
%
(
message_uuid
,
script_error_output
.
strip
()[:
255
])
)
)
return
script_output
return
script_output
except
Exception
as
script_exception
:
except
Exception
as
script_exception
:
...
...
src/opnsense/service/modules/template.py
View file @
f763963c
...
@@ -28,9 +28,6 @@
...
@@ -28,9 +28,6 @@
package : configd
package : configd
function: template handler, generate configuration files using templates
function: template handler, generate configuration files using templates
"""
"""
__author__
=
'Ad Schellevis'
import
os
import
os
import
os.path
import
os.path
import
syslog
import
syslog
...
@@ -40,9 +37,10 @@ import codecs
...
@@ -40,9 +37,10 @@ import codecs
import
jinja2
import
jinja2
import
addons.template_helpers
import
addons.template_helpers
__author__
=
'Ad Schellevis'
class
Template
(
object
):
class
Template
(
object
):
def
__init__
(
self
,
target_root_directory
=
"/"
):
def
__init__
(
self
,
target_root_directory
=
"/"
):
""" constructor
""" constructor
:return:
:return:
...
@@ -54,11 +52,12 @@ class Template(object):
...
@@ -54,11 +52,12 @@ class Template(object):
self
.
_target_root_directory
=
target_root_directory
self
.
_target_root_directory
=
target_root_directory
# setup jinja2 environment
# setup jinja2 environment
self
.
_template_dir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
+
'/../templates/'
self
.
_template_dir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
+
'/../templates/'
self
.
_j2_env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
self
.
_template_dir
),
trim_blocks
=
True
,
self
.
_j2_env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
self
.
_template_dir
),
trim_blocks
=
True
,
extensions
=
[
"jinja2.ext.do"
,])
extensions
=
[
"jinja2.ext.do"
,
])
def
_read_manifest
(
self
,
filename
):
@
staticmethod
def
_read_manifest
(
filename
):
"""
"""
:param filename: manifest filename (path/+MANIFEST)
:param filename: manifest filename (path/+MANIFEST)
...
@@ -72,7 +71,8 @@ class Template(object):
...
@@ -72,7 +71,8 @@ class Template(object):
return
result
return
result
def
_read_targets
(
self
,
filename
):
@
staticmethod
def
_read_targets
(
filename
):
""" read raw target filename masks
""" read raw target filename masks
:param filename: targets filename (path/+TARGETS)
:param filename: targets filename (path/+TARGETS)
...
@@ -118,18 +118,19 @@ class Template(object):
...
@@ -118,18 +118,19 @@ class Template(object):
return
result
return
result
def
set
C
onfig
(
self
,
config_data
):
def
set
_c
onfig
(
self
,
config_data
):
""" set config data
""" set config data
:param config_data: config data as dictionary/list structure
:param config_data: config data as dictionary/list structure
:return: None
:return: None
"""
"""
if
type
(
config_data
)
in
(
dict
,
collections
.
OrderedDict
):
if
type
(
config_data
)
in
(
dict
,
collections
.
OrderedDict
):
self
.
_config
=
config_data
self
.
_config
=
config_data
else
:
else
:
# no data given, reset
# no data given, reset
self
.
_config
=
{}
self
.
_config
=
{}
def
__find_string_tags
(
self
,
instr
):
@
staticmethod
def
__find_string_tags
(
instr
):
"""
"""
:param instr: string with optional tags [field.$$]
:param instr: string with optional tags [field.$$]
:return:
:return:
...
@@ -195,7 +196,8 @@ class Template(object):
...
@@ -195,7 +196,8 @@ class Template(object):
return
result
return
result
def
_create_directory
(
self
,
filename
):
@
staticmethod
def
_create_directory
(
filename
):
""" create directory
""" create directory
:param filename: create path for filename ( if not existing )
:param filename: create path for filename ( if not existing )
:return: None
:return: None
...
@@ -232,7 +234,7 @@ class Template(object):
...
@@ -232,7 +234,7 @@ class Template(object):
result_filenames
[
new_filename
]
=
copy
.
deepcopy
(
result_filenames
[
filename
])
result_filenames
[
new_filename
]
=
copy
.
deepcopy
(
result_filenames
[
filename
])
result_filenames
[
new_filename
][
key
]
=
target_filters
[
target_filter
][
key
]
result_filenames
[
new_filename
][
key
]
=
target_filters
[
target_filter
][
key
]
template_filename
=
'
%
s/
%
s'
%
(
module_name
.
replace
(
'.'
,
'/'
),
src_template
)
template_filename
=
'
%
s/
%
s'
%
(
module_name
.
replace
(
'.'
,
'/'
),
src_template
)
# parse template, make sure issues can be traced back to their origin
# parse template, make sure issues can be traced back to their origin
try
:
try
:
j2_page
=
self
.
_j2_env
.
get_template
(
template_filename
)
j2_page
=
self
.
_j2_env
.
get_template
(
template_filename
)
...
@@ -269,8 +271,8 @@ class Template(object):
...
@@ -269,8 +271,8 @@ class Template(object):
# it was in the original template.
# it was in the original template.
# It looks like Jinja sometimes isn't consistent on placing this last end-of-line in.
# It looks like Jinja sometimes isn't consistent on placing this last end-of-line in.
if
len
(
content
)
>
1
and
content
[
-
1
]
!=
'
\n
'
:
if
len
(
content
)
>
1
and
content
[
-
1
]
!=
'
\n
'
:
src_file
=
'
%
s
%
s'
%
(
self
.
_template_dir
,
template_filename
)
src_file
=
'
%
s
%
s'
%
(
self
.
_template_dir
,
template_filename
)
src_file_handle
=
open
(
src_file
,
'r'
)
src_file_handle
=
open
(
src_file
,
'r'
)
src_file_handle
.
seek
(
-
1
,
os
.
SEEK_END
)
src_file_handle
.
seek
(
-
1
,
os
.
SEEK_END
)
last_bytes_template
=
src_file_handle
.
read
()
last_bytes_template
=
src_file_handle
.
read
()
src_file_handle
.
close
()
src_file_handle
.
close
()
...
@@ -299,7 +301,7 @@ class Template(object):
...
@@ -299,7 +301,7 @@ class Template(object):
# direct match
# direct match
do_generate
=
True
do_generate
=
True
elif
wildcard_pos
==
-
1
and
len
(
module_name
)
<
len
(
template_name
)
\
elif
wildcard_pos
==
-
1
and
len
(
module_name
)
<
len
(
template_name
)
\
and
'
%
s.'
%
module_name
==
template_name
[
0
:
len
(
module_name
)
+
1
]:
and
'
%
s.'
%
module_name
==
template_name
[
0
:
len
(
module_name
)
+
1
]:
# match child item
# match child item
do_generate
=
True
do_generate
=
True
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment