allow multiple IP

This commit is contained in:
Emmanuel Garette 2021-02-26 22:22:38 +01:00
parent 3e7ae41061
commit 88f864cd2a
15 changed files with 166 additions and 44 deletions

View file

@ -52,7 +52,6 @@ class ServiceAnnotator:
""" """
def __init__(self, objectspace): def __init__(self, objectspace):
self.objectspace = objectspace self.objectspace = objectspace
self.uniq_ip = []
self.uniq_overrides = [] self.uniq_overrides = []
if 'network_type' not in self.objectspace.types: if 'network_type' not in self.objectspace.types:
self.objectspace.types['network_type'] = self.objectspace.types['ip_type'] self.objectspace.types['network_type'] = self.objectspace.types['ip_type']
@ -287,11 +286,6 @@ class ServiceAnnotator:
ip, ip,
service_name, service_name,
) -> None: ) -> None:
if service_name in self.uniq_ip:
msg = _('only one IP is allowed by service, '
'please use a variable multiple if you want have more than one IP')
raise DictConsistencyError(msg, 67, ip.xmlfiles)
self.uniq_ip.append(service_name)
variable = self.objectspace.paths.get_variable(ip.name, ip.xmlfiles) variable = self.objectspace.paths.get_variable(ip.name, ip.xmlfiles)
if variable.type not in ['ip', 'network', 'network_cidr']: if variable.type not in ['ip', 'network', 'network_cidr']:
msg = _(f'ip cannot be linked to "{variable.type}" variable "{ip.name}"') msg = _(f'ip cannot be linked to "{variable.type}" variable "{ip.name}"')

View file

@ -254,12 +254,15 @@ class RougailBaseTemplate:
else: else:
var = None var = None
func = f'_instance_{type}' func = f'_instance_{type}'
filename, source, destfile, var = getattr(self, func)(filevar, data = getattr(self, func)(filevar,
filename, filename,
service_name, service_name,
variable, variable,
idx, idx,
) )
if data is None:
continue
filename, source, destfile, var = data
destfilename = join(self.destinations_dir, destfile[1:]) destfilename = join(self.destinations_dir, destfile[1:])
makedirs(dirname(destfilename), exist_ok=True) makedirs(dirname(destfilename), exist_ok=True)
self.log.info(_(f"{filevar['engine']} processing: '{destfilename}'")) self.log.info(_(f"{filevar['engine']} processing: '{destfilename}'"))
@ -307,6 +310,7 @@ class RougailBaseTemplate:
self.instance_file(fill, type_, service_name) self.instance_file(fill, type_, service_name)
else: else:
self.log.debug(_("Instantiation of file '{filename}' disabled")) self.log.debug(_("Instantiation of file '{filename}' disabled"))
self.post_instance_service(service_name)
self.post_instance() self.post_instance()
chdir(ori_dir) chdir(ori_dir)
@ -315,6 +319,9 @@ class RougailBaseTemplate:
): ):
raise NotImplementedError(_('cannot desactivate a service')) raise NotImplementedError(_('cannot desactivate a service'))
def post_instance_service(self, service_name): # pragma: no cover
pass
def post_instance(self): # pragma: no cover def post_instance(self): # pragma: no cover
pass pass

View file

@ -20,7 +20,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from typing import Dict from typing import Dict, Any
from os import makedirs, symlink from os import makedirs, symlink
from os.path import dirname, isfile, join from os.path import dirname, isfile, join
from ipaddress import ip_network from ipaddress import ip_network
@ -62,6 +62,13 @@ z %%filename - - - - -
class RougailSystemdTemplate(RougailBaseTemplate): class RougailSystemdTemplate(RougailBaseTemplate):
def __init__(self, # pylint: disable=R0913
config: 'Config',
rougailconfig: 'RougailConfig'=None,
) -> None:
self.ip_per_service = None
super().__init__(config, rougailconfig)
def _instance_files(self, def _instance_files(self,
filevar: Dict, filevar: Dict,
destfile: str, destfile: str,
@ -95,25 +102,22 @@ class RougailSystemdTemplate(RougailBaseTemplate):
def _instance_ip(self, def _instance_ip(self,
filevar: Dict, filevar: Dict,
destfile, ip,
service_name: str, service_name: str,
var: Any,
idx: int,
*args, *args,
) -> tuple: ) -> tuple:
if self.ip_per_service is None:
self.ip_per_service = []
if 'netmask' in filevar: if 'netmask' in filevar:
if isinstance(filevar['name'], list): if isinstance(filevar["netmask"], list):
variable = [str(ip_network(f'{net}/{mask}')) netmask = filevar['netmask'][idx]
for net, mask in zip(filevar['name'], filevar['netmask'])]
else: else:
variable = str(ip_network(f'{filevar["name"]}/{filevar["netmask"]}')) netmask = filevar['netmask']
else: self.ip_per_service.append(str(ip_network(f'{ip}/{netmask}')))
variable = filevar['name'] elif ip:
if not isinstance(variable, list): self.ip_per_service.append(ip)
if variable is None:
variable = []
else:
variable = [variable]
filevar['engine'] = 'creole'
return None, ROUGAIL_IP_TEMPLATE, f'/systemd/system/{service_name}.service.d/rougail_ip.conf', variable
def desactive_service(self, def desactive_service(self,
service_name: str, service_name: str,
@ -122,6 +126,26 @@ class RougailSystemdTemplate(RougailBaseTemplate):
makedirs(dirname(filename), exist_ok=True) makedirs(dirname(filename), exist_ok=True)
symlink('/dev/null', filename) symlink('/dev/null', filename)
def post_instance_service(self,
service_name: str,
) -> None: # pragma: no cover
if self.ip_per_service is None:
return
destfile = f'/systemd/system/{service_name}.service.d/rougail_ip.conf'
destfilename = join(self.destinations_dir, destfile[1:])
makedirs(dirname(destfilename), exist_ok=True)
self.log.info(_(f"creole processing: '{destfilename}'"))
self.engines['creole'].process(filename=None,
source=ROUGAIL_IP_TEMPLATE,
true_destfilename=destfile,
destfilename=destfilename,
destdir=self.destinations_dir,
variable=self.ip_per_service,
rougail_variables_dict=self.rougail_variables_dict,
eosfunc=self.eosfunc,
)
self.ip_per_service = None
def post_instance(self): def post_instance(self):
destfile = '/tmpfiles.d/rougail.conf' destfile = '/tmpfiles.d/rougail.conf'
destfilename = join(self.destinations_dir, destfile[1:]) destfilename = join(self.destinations_dir, destfile[1:])

View file

@ -14,9 +14,5 @@
"rougail.general1.leader.follower2": { "rougail.general1.leader.follower2": {
"owner": [], "owner": [],
"value": [] "value": []
},
"rougail.general1.leader.follower3": {
"owner": [],
"value": []
} }
} }

View file

@ -14,9 +14,5 @@
"rougail.general1.leader.follower2": { "rougail.general1.leader.follower2": {
"owner": [], "owner": [],
"value": [] "value": []
},
"rougail.general1.leader.follower3": {
"owner": [],
"value": []
} }
} }

View file

@ -14,9 +14,5 @@
"rougail.general1.leader.follower2": { "rougail.general1.leader.follower2": {
"owner": [], "owner": [],
"value": [] "value": []
},
"rougail.general1.leader.follower3": {
"owner": [],
"value": []
} }
} }

View file

@ -14,9 +14,5 @@
"rougail.general1.leader.follower2": { "rougail.general1.leader.follower2": {
"owner": [], "owner": [],
"value": [] "value": []
},
"rougail.general1.leader.follower3": {
"owner": [],
"value": []
} }
} }

View file

@ -5,7 +5,7 @@
<services> <services>
<service name='nut'> <service name='nut'>
<ip>nut_monitor_host</ip> <ip>nut_monitor_host</ip>
<ip>nut_monitor_host</ip> <ip>nut_monitor_host2</ip>
</service> </service>
</services> </services>
@ -13,6 +13,9 @@
<variable name="nut_monitor_host" type="ip" mandatory='True'> <variable name="nut_monitor_host" type="ip" mandatory='True'>
<value>192.168.0.1</value> <value>192.168.0.1</value>
</variable> </variable>
<variable name="nut_monitor_host2" type="ip" mandatory='True'>
<value>192.168.0.2</value>
</variable>
</variables> </variables>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab

View file

@ -0,0 +1,34 @@
{
"rougail.nut_monitor_host": {
"owner": "default",
"value": "192.168.0.1"
},
"rougail.nut_monitor_host2": {
"owner": "default",
"value": "192.168.0.2"
},
"services.nut.ip.nut_monitor_host.name": {
"owner": "default",
"value": "192.168.0.1"
},
"services.nut.ip.nut_monitor_host.activate": {
"owner": "default",
"value": true
},
"services.nut.ip.nut_monitor_host2.name": {
"owner": "default",
"value": "192.168.0.2"
},
"services.nut.ip.nut_monitor_host2.activate": {
"owner": "default",
"value": true
},
"services.nut.activate": {
"owner": "default",
"value": true
},
"services.nut.manage": {
"owner": "default",
"value": true
}
}

View file

@ -0,0 +1,10 @@
{
"rougail.nut_monitor_host": "192.168.0.1",
"rougail.nut_monitor_host2": "192.168.0.2",
"services.nut.ip.nut_monitor_host.name": "192.168.0.1",
"services.nut.ip.nut_monitor_host.activate": true,
"services.nut.ip.nut_monitor_host2.name": "192.168.0.2",
"services.nut.ip.nut_monitor_host2.activate": true,
"services.nut.activate": true,
"services.nut.manage": true
}

View file

@ -0,0 +1,34 @@
{
"rougail.nut_monitor_host": {
"owner": "default",
"value": "192.168.0.1"
},
"rougail.nut_monitor_host2": {
"owner": "default",
"value": "192.168.0.2"
},
"services.nut.ip.nut_monitor_host.name": {
"owner": "default",
"value": "192.168.0.1"
},
"services.nut.ip.nut_monitor_host.activate": {
"owner": "default",
"value": true
},
"services.nut.ip.nut_monitor_host2.name": {
"owner": "default",
"value": "192.168.0.2"
},
"services.nut.ip.nut_monitor_host2.activate": {
"owner": "default",
"value": true
},
"services.nut.activate": {
"owner": "default",
"value": true
},
"services.nut.manage": {
"owner": "default",
"value": true
}
}

View file

@ -0,0 +1,4 @@
[Service]
IPAddressAllow=192.168.0.1
IPAddressAllow=192.168.0.2
IPAddressDeny=any

View file

@ -0,0 +1,28 @@
from importlib.machinery import SourceFileLoader
from importlib.util import spec_from_loader, module_from_spec
loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
spec = spec_from_loader(loader.name, loader)
func = module_from_spec(spec)
loader.exec_module(func)
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
option_2 = IPOption(name="nut_monitor_host", doc="nut_monitor_host", default="192.168.0.1", allow_reserved=True, properties=frozenset({"mandatory", "normal"}))
option_3 = IPOption(name="nut_monitor_host2", doc="nut_monitor_host2", default="192.168.0.2", allow_reserved=True, properties=frozenset({"mandatory", "normal"}))
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3])
option_8 = SymLinkOption(name="name", opt=option_2)
option_9 = BoolOption(name="activate", doc="activate", default=True)
option_7 = OptionDescription(name="nut_monitor_host", doc="nut_monitor_host", children=[option_8, option_9])
option_11 = SymLinkOption(name="name", opt=option_3)
option_12 = BoolOption(name="activate", doc="activate", default=True)
option_10 = OptionDescription(name="nut_monitor_host2", doc="nut_monitor_host2", children=[option_11, option_12])
option_6 = OptionDescription(name="ip", doc="ip", children=[option_7, option_10])
option_13 = BoolOption(name="activate", doc="activate", default=True)
option_14 = BoolOption(name="manage", doc="manage", default=True)
option_5 = OptionDescription(name="nut", doc="nut", children=[option_6, option_13, option_14])
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])