Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
scripts
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Thomas Blanc
scripts
Commits
a52ef72a
Commit
a52ef72a
authored
Jul 14, 2014
by
Pierre-Elliott Bécue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[trigger] MetaService en place, et amélioration du débug
parent
d2934339
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
202 additions
and
146 deletions
+202
-146
cranslib/clogger.py
cranslib/clogger.py
+10
-3
gestion/config/trigger.py
gestion/config/trigger.py
+2
-0
gestion/trigger/host.py
gestion/trigger/host.py
+1
-1
gestion/trigger/services/dhcp.py
gestion/trigger/services/dhcp.py
+93
-74
gestion/trigger/services/event.py
gestion/trigger/services/event.py
+12
-8
gestion/trigger/services/firewall.py
gestion/trigger/services/firewall.py
+20
-55
gestion/trigger/services/service.py
gestion/trigger/services/service.py
+54
-0
gestion/trigger/trigger.py
gestion/trigger/trigger.py
+10
-5
No files found.
cranslib/clogger.py
View file @
a52ef72a
...
@@ -13,9 +13,9 @@ class CLogger(logging.Logger):
...
@@ -13,9 +13,9 @@ class CLogger(logging.Logger):
Crans logger
Crans logger
"""
"""
def
__init__
(
self
,
loggerName
,
level
):
def
__init__
(
self
,
loggerName
,
service
,
level
,
debug
=
False
):
"""
"""
Initiali
se le logger
Initiali
zes logger. The debug variable is useful to have a print to stdout (when debugging)
"""
"""
super
(
CLogger
,
self
)
.
__init__
(
loggerName
)
super
(
CLogger
,
self
)
.
__init__
(
loggerName
)
...
@@ -27,10 +27,17 @@ class CLogger(logging.Logger):
...
@@ -27,10 +27,17 @@ class CLogger(logging.Logger):
self
.
fh
.
setLevel
(
self
.
fhlevel
)
self
.
fh
.
setLevel
(
self
.
fhlevel
)
# Creates formatter
# Creates formatter
self
.
formatter
=
logging
.
Formatter
(
'
%
(asctime)
s -
%(name)
s -
%(levelname)
s -
%(message)
s'
)
self
.
formatter
=
logging
.
Formatter
(
'
%
%(asctime)
s -
%%(name)
s -
%(service)
s -
%%(levelname)
s -
%%(message)
s'
%
{
'service'
:
service
}
)
# Adds formatter to FileHandler
# Adds formatter to FileHandler
self
.
fh
.
setFormatter
(
self
.
formatter
)
self
.
fh
.
setFormatter
(
self
.
formatter
)
if
debug
:
self
.
sh
=
logging
.
StreamHandler
()
self
.
shlevel
=
logging
.
DEBUG
self
.
sh
.
setLevel
(
self
.
shlevel
)
self
.
sh
.
setFormatter
(
self
.
formatter
)
self
.
addHandler
(
self
.
sh
)
# Adds FileHandler to Handlers
# Adds FileHandler to Handlers
self
.
addHandler
(
self
.
fh
)
self
.
addHandler
(
self
.
fh
)
gestion/config/trigger.py
View file @
a52ef72a
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
import
itertools
import
itertools
debug
=
True
# Serveur maître
# Serveur maître
master
=
"civet.adm.crans.org"
master
=
"civet.adm.crans.org"
...
...
gestion/trigger/host.py
View file @
a52ef72a
...
@@ -30,7 +30,7 @@ class TriggerFactory(object):
...
@@ -30,7 +30,7 @@ class TriggerFactory(object):
return
cls
.
_meths
.
values
()
return
cls
.
_meths
.
values
()
def
record
(
cls
):
def
record
(
cls
):
TriggerFactory
.
register
(
cls
.
__name__
,
cls
)
TriggerFactory
.
register
(
cls
.
__name__
.
lower
()
,
cls
)
def
trigger
(
what
):
def
trigger
(
what
):
return
TriggerFactory
.
get
(
what
)
return
TriggerFactory
.
get
(
what
)
gestion/trigger/services/dhcp.py
View file @
a52ef72a
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
# Licence : GPLv3
# Licence : GPLv3
import
lc_ldap.shortcuts
import
lc_ldap.shortcuts
from
gestion.trigger.host
import
record
import
gestion.config.trigger
as
trigger_config
from
gestion.trigger.services.service
import
BasicService
from
gestion.trigger.services.service
import
BasicService
from
cranslib.conffile
import
ConfFile
from
cranslib.conffile
import
ConfFile
import
cranslib.clogger
as
clogger
import
cranslib.clogger
as
clogger
...
@@ -23,82 +23,25 @@ from gestion.trigger.pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE
...
@@ -23,82 +23,25 @@ from gestion.trigger.pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE
from
gestion.trigger.pypureomapi
import
Omapi
,
OmapiMessage
from
gestion.trigger.pypureomapi
import
Omapi
,
OmapiMessage
import
struct
import
struct
logger
=
clogger
.
CLogger
(
"trigger
.dhcp"
,
"debug"
)
logger
=
clogger
.
CLogger
(
"trigger
"
,
"dhcp"
,
"debug"
,
trigger_config
.
debug
)
hostname
=
socket
.
gethostname
()
.
split
(
"."
)[
0
]
+
".adm.crans.org"
hostname
=
socket
.
gethostname
()
.
split
(
"."
)[
0
]
+
".adm.crans.org"
dhcp_omapi_keyname
=
secrets_new
.
get
(
"dhcp_omapi_keyname"
)
dhcp_omapi_key
=
secrets_new
.
get
(
"dhcp_omapi_keys"
)[
hostname
]
ldap_conn
=
lc_ldap
.
shortcuts
.
lc_ldap_readonly
()
ldap_conn
=
lc_ldap
.
shortcuts
.
lc_ldap_readonly
()
def
add_dhcp_host
(
mac
,
ip
,
name
=
None
):
"""Adds a dhcp host using omapi
"""
class
Dhcp
(
BasicService
):
if
'<automatique>'
in
[
ip
,
mac
]:
return
msg
=
OmapiMessage
.
open
(
b
"host"
)
msg
.
message
.
append
((
b
"create"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
message
.
append
((
b
"exclusive"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
obj
.
append
((
b
"hardware-address"
,
pack_mac
(
mac
)))
msg
.
obj
.
append
((
b
"hardware-type"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
obj
.
append
((
b
"ip-address"
,
pack_ip
(
ip
)))
if
name
:
msg
.
obj
.
append
((
b
"name"
,
bytes
(
name
)))
conn
=
Omapi
(
hostname
,
9991
,
dhcp_omapi_keyname
,
dhcp_omapi_key
)
response
=
conn
.
query_server
(
msg
)
conn
.
close
()
def
delete_dhcp_host
(
mac
,
ip
):
"""Deletes dhcp host using omapi
"""
if
'<automatique>'
in
[
ip
,
mac
]:
return
msg
=
OmapiMessage
.
open
(
b
"host"
)
msg
.
obj
.
append
((
b
"hardware-address"
,
pack_mac
(
mac
)))
msg
.
obj
.
append
((
b
"hardware-type"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
obj
.
append
((
b
"ip-address"
,
pack_ip
(
ip
)))
conn
=
Omapi
(
hostname
,
9991
,
dhcp_omapi_keyname
,
dhcp_omapi_key
)
response
=
conn
.
query_server
(
msg
)
if
response
.
opcode
==
OMAPI_OP_UPDATE
:
response
=
conn
.
query_server
(
OmapiMessage
.
delete
(
response
.
handle
))
conn
.
close
()
def
lease_clean
():
"""Clean the lease file
"""
# TODO : use ConfigFile structure
leasefile
=
open
(
dhcp_config
.
dhcplease
)
newleasefile
=
open
(
dhcp_config
.
dhcplease
+
'.new'
,
'w'
)
config
=
""
line
=
leasefile
.
readline
()
write
=
True
while
line
:
if
line
.
strip
()
.
startswith
(
'host'
):
write
=
False
if
write
:
newleasefile
.
write
(
line
)
if
not
write
and
line
.
strip
()
.
endswith
(
'}'
):
write
=
True
line
=
leasefile
.
readline
()
leasefile
.
close
()
newleasefile
.
close
()
os
.
rename
(
dhcp_config
.
dhcplease
+
'.new'
,
dhcp_config
.
dhcplease
)
@
record
class
dhcp
(
BasicService
):
"""Class responsible of dhcp service.
"""Class responsible of dhcp service.
"""
"""
# Class lookup table to define which changes call which function.
# Class lookup table to define which changes call which function.
changes_trigger
=
{
changes_trigger
=
{
lc_ldap
.
attributs
.
macAddress
.
ldap_name
:
(
dhcp
.
send_mac_ip
,),
lc_ldap
.
attributs
.
macAddress
.
ldap_name
:
(
'send_mac_ip'
,),
lc_ldap
.
attributs
.
ipHostNumber
.
ldap_name
:
(
dhcp
.
send_mac_ip
,),
lc_ldap
.
attributs
.
ipHostNumber
.
ldap_name
:
(
'send_mac_ip'
,),
}
}
dhcp_omapi_keyname
=
None
dhcp_omapi_key
=
None
#secrets_new.get("dhcp_omapi_keys")[hostname]
@
classmethod
@
classmethod
def
send_mac_ip
(
cls
,
body
,
diff
):
def
send_mac_ip
(
cls
,
body
,
diff
):
"""Computes mac_ip data to send from body and diff
"""Computes mac_ip data to send from body and diff
...
@@ -111,14 +54,14 @@ class dhcp(BasicService):
...
@@ -111,14 +54,14 @@ class dhcp(BasicService):
# Régénération du DHCP :
# Régénération du DHCP :
if
not
macs
[
0
]:
if
not
macs
[
0
]:
# Création d'une nouvelle machine.
# Création d'une nouvelle machine.
dhcp
=
{
'add'
:
[(
macs
[
1
],
ips
[
1
],
hostnames
[
1
])]}
dhcp
_dict
=
{
'add'
:
[(
macs
[
1
],
ips
[
1
],
hostnames
[
1
])]}
elif
not
macs
[
1
]:
elif
not
macs
[
1
]:
# Destruction d'une machine.
# Destruction d'une machine.
dhcp
=
{
'delete'
:
[(
macs
[
0
],
ips
[
0
])]}
dhcp
_dict
=
{
'delete'
:
[(
macs
[
0
],
ips
[
0
])]}
else
:
else
:
# Mise à jour.
# Mise à jour.
dhcp
=
{
'update'
:
[(
macs
[
0
],
ips
[
0
],
macs
[
1
],
ips
[
1
],
hostnames
[
1
])]}
dhcp
_dict
=
{
'update'
:
[(
macs
[
0
],
ips
[
0
],
macs
[
1
],
ips
[
1
],
hostnames
[
1
])]}
return
(
"dhcp"
,
dhcp
)
return
(
"dhcp"
,
dhcp
_dict
)
@
classmethod
@
classmethod
def
regen
(
cls
,
body
=
None
):
def
regen
(
cls
,
body
=
None
):
...
@@ -132,12 +75,12 @@ class dhcp(BasicService):
...
@@ -132,12 +75,12 @@ class dhcp(BasicService):
if
body
and
isinstance
(
body
,
dict
):
if
body
and
isinstance
(
body
,
dict
):
for
(
mac
,
ip
,
name
)
in
body
.
get
(
"add"
,
[]):
for
(
mac
,
ip
,
name
)
in
body
.
get
(
"add"
,
[]):
add_dhcp_host
(
mac
,
ip
,
name
)
cls
.
add_dhcp_host
(
mac
,
ip
,
name
)
for
(
mac
,
ip
)
in
body
.
get
(
"delete"
,
[]):
for
(
mac
,
ip
)
in
body
.
get
(
"delete"
,
[]):
delete_dhcp_host
(
mac
,
ip
)
cls
.
delete_dhcp_host
(
mac
,
ip
)
for
(
rmac
,
rip
,
mac
,
ip
,
name
)
in
body
.
get
(
"update"
,
[]):
for
(
rmac
,
rip
,
mac
,
ip
,
name
)
in
body
.
get
(
"update"
,
[]):
delete_dhcp_host
(
rmac
,
rip
)
cls
.
delete_dhcp_host
(
rmac
,
rip
)
add_dhcp_host
(
mac
,
ip
,
name
)
cls
.
add_dhcp_host
(
mac
,
ip
,
name
)
elif
body
==
True
:
elif
body
==
True
:
hosts
=
{}
hosts
=
{}
host_template
=
"""
host_template
=
"""
...
@@ -186,9 +129,85 @@ class dhcp(BasicService):
...
@@ -186,9 +129,85 @@ class dhcp(BasicService):
step
=
"Nettoyage des fichiers de leases"
step
=
"Nettoyage des fichiers de leases"
affichage
.
prettyDoin
(
step
,
"..."
)
affichage
.
prettyDoin
(
step
,
"..."
)
try
:
try
:
lease_clean
()
cls
.
lease_clean
()
affichage
.
prettyDoin
(
step
,
"Ok"
)
affichage
.
prettyDoin
(
step
,
"Ok"
)
except
:
except
:
affichage
.
prettyDoin
(
step
,
"Erreur"
)
affichage
.
prettyDoin
(
step
,
"Erreur"
)
print
"During lease clean, an error occured."
print
"During lease clean, an error occured."
raise
raise
@
classmethod
def
check_secrets
(
cls
):
"""This method allows lazy evaluation for dhcp_omapi_keyname
and dhcp_omapi_key, since event imports all services. This is actually
the best lazy eval we can hope, since property won't work on
classmethods.
"""
if
cls
.
dhcp_omapi_keyname
is
None
:
cls
.
dhcp_omapi_keyname
=
secrets_new
.
get
(
"dhcp_omapi_keyname"
)
if
cls
.
dhcp_omapi_key
is
None
:
cls
.
dhcp_omapi_key
=
secrets_new
.
get
(
"dhcp_omapi_keys"
)[
hostname
]
@
classmethod
def
add_dhcp_host
(
cls
,
mac
,
ip
,
name
=
None
):
"""Adds a dhcp host using omapi
"""
cls
.
check_secrets
()
if
'<automatique>'
in
[
ip
,
mac
]:
return
msg
=
OmapiMessage
.
open
(
b
"host"
)
msg
.
message
.
append
((
b
"create"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
message
.
append
((
b
"exclusive"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
obj
.
append
((
b
"hardware-address"
,
pack_mac
(
mac
)))
msg
.
obj
.
append
((
b
"hardware-type"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
obj
.
append
((
b
"ip-address"
,
pack_ip
(
ip
)))
if
name
:
msg
.
obj
.
append
((
b
"name"
,
bytes
(
name
)))
conn
=
Omapi
(
hostname
,
9991
,
cls
.
dhcp_omapi_keyname
,
cls
.
dhcp_omapi_key
)
_
=
conn
.
query_server
(
msg
)
conn
.
close
()
@
classmethod
def
delete_dhcp_host
(
cls
,
mac
,
ip
):
"""Deletes dhcp host using omapi
"""
cls
.
check_secrets
()
if
'<automatique>'
in
[
ip
,
mac
]:
return
msg
=
OmapiMessage
.
open
(
b
"host"
)
msg
.
obj
.
append
((
b
"hardware-address"
,
pack_mac
(
mac
)))
msg
.
obj
.
append
((
b
"hardware-type"
,
struct
.
pack
(
"!I"
,
1
)))
msg
.
obj
.
append
((
b
"ip-address"
,
pack_ip
(
ip
)))
conn
=
Omapi
(
hostname
,
9991
,
cls
.
dhcp_omapi_keyname
,
cls
.
dhcp_omapi_key
)
response
=
conn
.
query_server
(
msg
)
if
response
.
opcode
==
OMAPI_OP_UPDATE
:
_
=
conn
.
query_server
(
OmapiMessage
.
delete
(
response
.
handle
))
conn
.
close
()
@
staticmethod
def
lease_clean
():
"""Clean the lease file
"""
# TODO : use ConfigFile structure
leasefile
=
open
(
dhcp_config
.
dhcplease
)
newleasefile
=
open
(
dhcp_config
.
dhcplease
+
'.new'
,
'w'
)
line
=
leasefile
.
readline
()
write
=
True
while
line
:
if
line
.
strip
()
.
startswith
(
'host'
):
write
=
False
if
write
:
newleasefile
.
write
(
line
)
if
not
write
and
line
.
strip
()
.
endswith
(
'}'
):
write
=
True
line
=
leasefile
.
readline
()
leasefile
.
close
()
newleasefile
.
close
()
os
.
rename
(
dhcp_config
.
dhcplease
+
'.new'
,
dhcp_config
.
dhcplease
)
gestion/trigger/services/event.py
View file @
a52ef72a
...
@@ -18,6 +18,7 @@ import cPickle
...
@@ -18,6 +18,7 @@ import cPickle
import
pika
import
pika
import
importlib
import
importlib
import
itertools
import
itertools
import
traceback
# Trigger features
# Trigger features
import
gestion.config.trigger
as
trigger_config
import
gestion.config.trigger
as
trigger_config
...
@@ -30,20 +31,24 @@ import cranslib.clogger as clogger
...
@@ -30,20 +31,24 @@ import cranslib.clogger as clogger
# lc_ldap
# lc_ldap
import
lc_ldap.attributs
import
lc_ldap.attributs
logger
=
clogger
.
CLogger
(
"trigger
.event"
,
"info"
)
logger
=
clogger
.
CLogger
(
"trigger
"
,
"event"
,
"debug"
,
trigger_config
.
debug
)
services
=
[
importlib
.
import_module
(
"gestion.trigger.services.
%
s"
%
(
config_service
,))
for
config_service
in
trigger_config
.
all_services
]
for
config_service
in
trigger_config
.
all_services
:
try
:
services
.
append
(
importlib
.
import_module
(
"gestion.trigger.services.
%
s"
%
(
config_service
,)))
except
Exception
as
e
:
logger
.
critical
(
"Fatal : import of
%
r failed, see following traceback.
%
r"
,
config_service
,
traceback
.
format_exc
())
class
Event
(
cmb
.
BasicProducer
):
class
Event
Producer
(
cmb
.
BasicProducer
):
"""
"""
Event tracker
Event
Producer
tracker
"""
"""
def
__init__
(
self
,
app_id
):
def
__init__
(
self
,
app_id
):
"""Extended
"""Extended
"""
"""
logger
.
info
(
"Starting trigger Event program…"
)
logger
.
info
(
"Starting trigger Event
Producer
program…"
)
super
(
Event
,
self
)
.
__init__
(
trigger_config
.
master
,
'trigger'
,
app_id
)
super
(
Event
Producer
,
self
)
.
__init__
(
trigger_config
.
master
,
'trigger'
,
app_id
)
self
.
_connection
=
self
.
connect
()
self
.
_connection
=
self
.
connect
()
self
.
get_chan
()
self
.
get_chan
()
...
@@ -127,7 +132,6 @@ def compare_lists(list1, list2):
...
@@ -127,7 +132,6 @@ def compare_lists(list1, list2):
return
moins
,
plus
return
moins
,
plus
@
record
class
event
(
BasicService
):
class
event
(
BasicService
):
"""Event service class. It extends BasicService, but should not implement
"""Event service class. It extends BasicService, but should not implement
any change trigger, since it's this service which is designed to call
any change trigger, since it's this service which is designed to call
...
@@ -187,5 +191,5 @@ class event(BasicService):
...
@@ -187,5 +191,5 @@ class event(BasicService):
# trigger_send(*msg)
# trigger_send(*msg)
def
trigger_send
(
routing_key
,
body
):
def
trigger_send
(
routing_key
,
body
):
sender
=
Event
(
"civet"
)
sender
=
Event
Producer
(
"civet"
)
sender
.
send_message
(
"trigger.
%
s"
%
(
routing_key
,),
body
)
sender
.
send_message
(
"trigger.
%
s"
%
(
routing_key
,),
body
)
gestion/trigger/services/firewall.py
View file @
a52ef72a
...
@@ -15,57 +15,22 @@ it to regenerate what needs to.
...
@@ -15,57 +15,22 @@ it to regenerate what needs to.
"""
"""
import
lc_ldap.shortcuts
import
lc_ldap.shortcuts
from
gestion.trigger.host
import
record
import
gestion.config.trigger
as
trigger_config
from
gestion.trigger.services.service
import
BasicService
from
gestion.trigger.services.service
import
BasicService
import
cranslib.clogger
as
clogger
import
cranslib.clogger
as
clogger
import
gestion.config.firewall
as
firewall_config
import
gestion.trigger.firewall4.firewall4
as
firewall4
import
gestion.trigger.firewall4.firewall4
as
firewall4
logger
=
clogger
.
CLogger
(
"trigger
.firewall"
,
"debug"
)
logger
=
clogger
.
CLogger
(
"trigger
"
,
"firewall"
,
"debug"
,
trigger_config
.
debug
)
class
FwFunFactory
(
object
):
class
Firewall
(
BasicService
):
"""Factory containing which function is part of the trigger set
"""
_meths
=
{}
@
classmethod
def
register
(
cls
,
key
,
value
):
"""Stores in factory the function name and its value
"""
cls
.
_meths
[
key
]
=
value
@
classmethod
def
get
(
cls
,
key
):
"""Gets what is stored
"""
return
cls
.
_meths
.
get
(
key
,
None
)
def
fwrecord
(
function
):
"""Records function in FwFunFactory
"""
FwFunFactory
.
register
(
function
.
func_name
,
function
)
def
fwcall
(
fwfun
):
"""Calls in function from FwFunFactory
"""
return
FwFunFactory
.
get
(
fwfun
)
@
record
class
firewall
(
BasicService
):
"""Firewall service that handles any modification in the firewall.
"""Firewall service that handles any modification in the firewall.
"""
"""
# Class lookup table to define which changes call which function.
# Class lookup table to define which changes call which function.
changes_trigger
=
{
changes_trigger
=
{
lc_ldap
.
attributs
.
macAddress
.
ldap_name
:
(
firewall
.
send_mac_ip
,),
lc_ldap
.
attributs
.
macAddress
.
ldap_name
:
(
'send_mac_ip'
,),
lc_ldap
.
attributs
.
ipHostNumber
.
ldap_name
:
(
firewall
.
send_mac_ip
,),
lc_ldap
.
attributs
.
ipHostNumber
.
ldap_name
:
(
'send_mac_ip'
,),
}
}
@
classmethod
@
classmethod
...
@@ -98,19 +63,19 @@ class firewall(BasicService):
...
@@ -98,19 +63,19 @@ class firewall(BasicService):
return
return
(
service
,
data
)
=
body
(
service
,
data
)
=
body
logger
.
info
(
"Calling service
%
s for data
%
r"
,
service
,
data
)
logger
.
info
(
"Calling service
%
s for data
%
r"
,
service
,
data
)
fwcall
(
service
)(
data
)
getattr
(
cls
,
service
)(
data
)
@
fwrecor
d
@
classmetho
d
def
mac_ip
(
body
):
def
mac_ip
(
cls
,
body
):
host_fw
=
firewall4
.
firewall
()
host_fw
=
firewall4
.
firewall
()
if
body
and
isinstance
(
body
,
dict
):
if
body
and
isinstance
(
body
,
dict
):
for
(
mac
,
ip
)
in
body
.
get
(
"add"
,
[]):
for
(
mac
,
ip
)
in
body
.
get
(
"add"
,
[]):
logger
.
info
(
"Adding mac_ip
%
s,
%
s"
,
mac
,
ip
)
logger
.
info
(
"Adding mac_ip
%
s,
%
s"
,
mac
,
ip
)
host_fw
.
mac_ip_append
(
mac
,
ip
)
host_fw
.
mac_ip_append
(
mac
,
ip
)
for
(
mac
,
ip
)
in
body
.
get
(
"delete"
,
[]):
for
(
mac
,
ip
)
in
body
.
get
(
"delete"
,
[]):
logger
.
info
(
"Removing mac_ip
%
s,
%
s"
,
mac
,
ip
)
logger
.
info
(
"Removing mac_ip
%
s,
%
s"
,
mac
,
ip
)
host_fw
.
mac_ip_remove
(
mac
,
ip
)
host_fw
.
mac_ip_remove
(
mac
,
ip
)
for
(
rmac
,
rip
,
mac
,
ip
)
in
body
.
get
(
"update"
,
[]):
for
(
rmac
,
rip
,
mac
,
ip
)
in
body
.
get
(
"update"
,
[]):
logger
.
info
(
"Updating mac_ip
%
s,
%
s with
%
s,
%
s"
,
rmac
,
rip
,
mac
,
ip
)
logger
.
info
(
"Updating mac_ip
%
s,
%
s with
%
s,
%
s"
,
rmac
,
rip
,
mac
,
ip
)
host_fw
.
mac_ip_remove
(
rmac
,
rip
)
host_fw
.
mac_ip_remove
(
rmac
,
rip
)
host_fw
.
mac_ip_append
(
mac
,
ip
)
host_fw
.
mac_ip_append
(
mac
,
ip
)
gestion/trigger/services/service.py
View file @
a52ef72a
...
@@ -6,11 +6,65 @@ This module provides a basic service class to other services. It should *NOT*
...
@@ -6,11 +6,65 @@ This module provides a basic service class to other services. It should *NOT*
be referenced in configuration of trigger.
be referenced in configuration of trigger.
"""
"""
import
collections
import
cranslib.clogger
as
clogger
import
gestion.config.trigger
as
trigger_config
from
gestion.trigger.host
import
TriggerFactory
logger
=
clogger
.
CLogger
(
"trigger"
,
"service"
,
"debug"
,
trigger_config
.
debug
)
class
MetaService
(
type
):
"""Metaclass designed to handle all services.
"""
def
__new__
(
mcs
,
cname
,
cpar
,
cattrs
):
"""Method producing the new class itself
At first, I wanted to put the changes_trigger modification in __new__,
using direct modification of cattrs['changes_trigger'] by pointing the
required methods (classmethods). The problem was that these methods were
bound at the return of type.__new__, for a reason I could not exactly
explain.
I found a workaround using __init__, so the point would be to remove
__new__, and directly use type.__new__, but this comment seems useful,
so __new__ will survive.
"""
return
super
(
MetaService
,
mcs
)
.
__new__
(
mcs
,
cname
,
cpar
,
cattrs
)
def
__init__
(
cls
,
cname
,
cpar
,
cattrs
):
"""Used to register the generated classes in TriggerFactory, and modify the behavior of
changes_trigger by pointing functions instead of their names. This allows to cancel any
positional requirement in class definition.
Do NEVER return something in __init__ function.
"""
if
not
cname
==
"BasicService"
:
TriggerFactory
.
register
(
cname
.
lower
(),
cls
)
changes_trigger
=
collections
.
defaultdict
(
list
)
# I love getattr
text_changes_trigger
=
getattr
(
cls
,
"changes_trigger"
,
{})
for
(
ldap_attr_name
,
funcs_name
)
in
text_changes_trigger
.
items
():
for
func_name
in
funcs_name
:
# I really love getattr.
get
=
getattr
(
cls
,
func_name
,
None
)
if
get
is
None
:
logger
.
critical
(
"Fatal, bad function (
%
r) reference in
%
r."
,
func_name
,
cname
)
continue
changes_trigger
[
ldap_attr_name
]
.
append
(
get
)
setattr
(
cls
,
"changes_trigger"
,
changes_trigger
)
super
(
MetaService
,
cls
)
.
__init__
(
cname
,
cpar
,
cattrs
)
class
BasicService
(
object
):
class
BasicService
(
object
):
"""Basic service handler. Other services should inherit fron this one.
"""Basic service handler. Other services should inherit fron this one.
"""
"""
__metaclass__
=
MetaService
changes_trigger
=
{}
changes_trigger
=
{}
@
classmethod
@
classmethod
...
...
gestion/trigger/trigger.py
View file @
a52ef72a
...
@@ -11,16 +11,19 @@
...
@@ -11,16 +11,19 @@
# Date : 29/04/2014
# Date : 29/04/2014
import
argparse
import
argparse
import
cranslib.clogger
as
clogger
import
cmb
import
cPickle
import
cPickle
import
socket
import
socket
import
traceback
import
sys
import
gestion.config.trigger
as
trigger_config
import
gestion.config.trigger
as
trigger_config
import
gestion.affichage
as
affichage
import
gestion.affichage
as
affichage
import
sys
from
gestion.trigger.host
import
trigger
from
gestion.trigger.host
import
trigger
import
cranslib.clogger
as
clogger
import
cmb
hostname
=
socket
.
gethostname
()
.
split
(
"."
)[
0
]
hostname
=
socket
.
gethostname
()
.
split
(
"."
)[
0
]
logger
=
clogger
.
CLogger
(
"trigger"
,
"trigger"
,
"info"
,
trigger_config
.
debug
)
# Ce bloc contient le peu de "magie" de la librairie, on utilise les services listés dans config/trigger.py
# Ce bloc contient le peu de "magie" de la librairie, on utilise les services listés dans config/trigger.py
# comme référence. Pour éviter toute redondance, la commande importe donc les services utiles suivant cette
# comme référence. Pour éviter toute redondance, la commande importe donc les services utiles suivant cette
...
@@ -30,8 +33,10 @@ hostname = socket.gethostname().split(".")[0]
...
@@ -30,8 +33,10 @@ hostname = socket.gethostname().split(".")[0]
import
importlib
import
importlib
services
=
{}
services
=
{}
for
config_service
in
trigger_config
.
services
[
hostname
]:
for
config_service
in
trigger_config
.
services
[
hostname
]:
services
[
config_service
]
=
importlib
.
import_module
(
"gestion.trigger.services.
%
s"
%
(
config_service
,))
try
:
logger
=
clogger
.
CLogger
(
"trigger"
,
"info"
)
services
[
config_service
]
=
importlib
.
import_module
(
"gestion.trigger.services.
%
s"
%
(
config_service
,))
except
Exception
as
e
:
logger
.
critical
(
"Fatal : import of
%
r failed, see following traceback.
%
r"
,
config_service
,
traceback
.
format_exc
())
class
EvenementListener
(
cmb
.
AsynchronousConsumer
):
class
EvenementListener
(
cmb
.
AsynchronousConsumer
):
"""
"""
...
...
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