"""dsc_datatool.transformer.net_remap See `man dsc-datatool-transformer netremap`. Part of dsc_datatool. :copyright: 2024 OARC, Inc. """ import ipaddress from dsc_datatool import Transformer, args class NetRemap(Transformer): v4net = None v6net = None nonstrict = False def __init__(self, opts): Transformer.__init__(self, opts) net = opts.get('net', None) self.v4net = opts.get('v4net', net) self.v6net = opts.get('v6net', net) if not self.v4net: raise Exception('v4net (or net) must be given') if not self.v6net: raise Exception('v6net (or net) must be given') if opts.get('nonstrict', False): self.nonstrict = True def _process(self, dimension): if not dimension.values: for d2 in dimension.dimensions: self._process(d2) return values = dimension.values dimension.values = {} for k, v in values.items(): if k == args.skipped_key: continue elif k == args.skipped_sum_key: dimension.values['0'] = v continue try: ip = ipaddress.ip_address(k) except Exception as e: if not self.nonstrict: raise e continue if ip.version == 4: nkey = str(ipaddress.IPv4Network('%s/%s' % (ip, self.v4net), strict=False).network_address) else: nkey = str(ipaddress.IPv6Network('%s/%s' % (ip, self.v6net), strict=False).network_address) if not nkey in dimension.values: dimension.values[nkey] = v else: dimension.values[nkey] += v def process(self, datasets): for dataset in datasets: for dimension in dataset.dimensions: self._process(dimension) import sys if sys.version_info[0] == 3 and sys.version_info[1] == 5: # pragma: no cover Transformer.__init_subclass__(NetRemap)