def _generate_radvd_conf(self, router_ports): radvd_conf = utils.get_conf_file_name(self._agent_conf.ra_confs, self._router_id, 'radvd.conf', True) buf = six.StringIO() for p in router_ports: subnets = p.get('subnets', []) v6_subnets = [subnet for subnet in subnets if netaddr.IPNetwork(subnet['cidr']).version == 6] if not v6_subnets: continue ra_modes = {subnet['ipv6_ra_mode'] for subnet in v6_subnets} auto_config_prefixes = [subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC or subnet['ipv6_ra_mode'] == constants.DHCPV6_STATELESS] stateful_config_prefixes = [subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.DHCPV6_STATEFUL] interface_name = self._dev_name_helper(p['id']) slaac_subnets = [subnet for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC] dns_servers = list(iter_chain(*[subnet['dns_nameservers'] for subnet in slaac_subnets if subnet.get('dns_nameservers')])) buf.write('%s' % CONFIG_TEMPLATE.render( ra_modes=list(ra_modes), interface_name=interface_name, auto_config_prefixes=auto_config_prefixes, stateful_config_prefixes=stateful_config_prefixes, dns_servers=dns_servers[0:MAX_RDNSS_ENTRIES], constants=constants, min_rtr_adv_interval=self._agent_conf.min_rtr_adv_interval, max_rtr_adv_interval=self._agent_conf.max_rtr_adv_interval)) common_utils.replace_file(radvd_conf, buf.getvalue()) return radvd_conf
def test_replace_file_custom_mode_twice(self): file_mode = 0o722 utils.replace_file(self.file_name, self.data, file_mode) self.data = "new data to copy" file_mode = 0o777 utils.replace_file(self.file_name, self.data, file_mode) self._verify_result(file_mode)
def _generate_radvd_conf(self, router_ports): radvd_conf = utils.get_conf_file_name(cfg.CONF.ra_confs, self._router_id, 'radvd.conf', True) buf = six.StringIO() for p in router_ports: subnets = p.get('subnets', []) v6_subnets = [subnet for subnet in subnets if netaddr.IPNetwork(subnet['cidr']).version == 6] if not v6_subnets: continue ra_modes = {subnet['ipv6_ra_mode'] for subnet in v6_subnets} auto_config_prefixes = [subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC or subnet['ipv6_ra_mode'] == constants.DHCPV6_STATELESS] interface_name = self._dev_name_helper(p['id']) buf.write('%s' % CONFIG_TEMPLATE.render( ra_modes=list(ra_modes), interface_name=interface_name, prefixes=auto_config_prefixes, constants=constants)) common_utils.replace_file(radvd_conf, buf.getvalue()) return radvd_conf
def _generate_radvd_conf(self, router_ports): radvd_conf = utils.get_conf_file_name(cfg.CONF.ra_confs, self._router_id, 'radvd.conf', True) buf = six.StringIO() for p in router_ports: subnets = p.get('subnets', []) v6_subnets = [ subnet for subnet in subnets if netaddr.IPNetwork(subnet['cidr']).version == 6 ] if not v6_subnets: continue ra_modes = {subnet['ipv6_ra_mode'] for subnet in v6_subnets} auto_config_prefixes = [ subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC or subnet['ipv6_ra_mode'] == constants.DHCPV6_STATELESS ] interface_name = self._dev_name_helper(p['id']) buf.write('%s' % CONFIG_TEMPLATE.render(ra_modes=list(ra_modes), interface_name=interface_name, prefixes=auto_config_prefixes, constants=constants)) common_utils.replace_file(radvd_conf, buf.getvalue()) return radvd_conf
def ensure_config_file(self, kind, template, vpnservice, file_mode=None): """Update config file, based on current settings for service.""" config_str = self._gen_config_content(template, vpnservice) config_file_name = self._get_config_filename(kind) if file_mode is None: n_utils.replace_file(config_file_name, config_str) else: n_utils.replace_file(config_file_name, config_str, file_mode)
def _output_opts_file(self): """Write a dnsmasq compatible options file.""" options, subnet_index_map = self._generate_opts_per_subnet() options += self._generate_opts_per_port(subnet_index_map) name = self.get_conf_file_name("opts") common_utils.replace_file(name, "\n".join(options)) return name
def save_config(conf_path, logical_config, socket_path=None, user_group='nogroup'): """Convert a logical configuration to the HAProxy version.""" data = [] data.extend(_build_global(logical_config, socket_path=socket_path, user_group=user_group)) data.extend(_build_defaults(logical_config)) data.extend(_build_frontend(logical_config)) data.extend(_build_backend(logical_config)) n_utils.replace_file(conf_path, '\n'.join(data))
def _output_hosts_file(self): """Writes a dnsmasq compatible dhcp hosts file. The generated file is sent to the --dhcp-hostsfile option of dnsmasq, and lists the hosts on the network which should receive a dhcp lease. Each line in this file is in the form:: 'mac_address,FQDN,ip_address' IMPORTANT NOTE: a dnsmasq instance does not resolve hosts defined in this file if it did not give a lease to a host listed in it (e.g.: multiple dnsmasq instances on the same network if this network is on multiple network nodes). This file is only defining hosts which should receive a dhcp lease, the hosts resolution in itself is defined by the `_output_addn_hosts_file` method. """ buf = six.StringIO() filename = self.get_conf_file_name("host") LOG.debug("Building host file: %s", filename) dhcp_enabled_subnet_ids = [s.id for s in self.network.subnets if s.enable_dhcp] # NOTE(ihrachyshka): the loop should not log anything inside it, to # avoid potential performance drop when lots of hosts are dumped for host_tuple in self._iter_hosts(): port, alloc, hostname, name, no_dhcp, no_opts = host_tuple if no_dhcp: if not no_opts and self._get_port_extra_dhcp_opts(port): buf.write("%s,%s%s\n" % (port.mac_address, "set:", port.id)) continue # don't write ip address which belongs to a dhcp disabled subnet. if alloc.subnet_id not in dhcp_enabled_subnet_ids: continue ip_address = self._format_address_for_dnsmasq(alloc.ip_address) if self._get_port_extra_dhcp_opts(port): client_id = self._get_client_id(port) if client_id and len(port.extra_dhcp_opts) > 1: buf.write( "%s,%s%s,%s,%s,%s%s\n" % (port.mac_address, self._ID, client_id, name, ip_address, "set:", port.id) ) elif client_id and len(port.extra_dhcp_opts) == 1: buf.write("%s,%s%s,%s,%s\n" % (port.mac_address, self._ID, client_id, name, ip_address)) else: buf.write("%s,%s,%s,%s%s\n" % (port.mac_address, name, ip_address, "set:", port.id)) else: buf.write("%s,%s,%s\n" % (port.mac_address, name, ip_address)) common_utils.replace_file(filename, buf.getvalue()) LOG.debug("Done building host file %s with contents:\n%s", filename, buf.getvalue()) return filename
def _store_listener_crt(haproxy_base_dir, listener, cert): """Store TLS certificate :param haproxy_base_dir: location of the instances state data :param listener: the listener object :param cert: the TLS certificate :returns: location of the stored certificate """ cert_path = _retrieve_crt_path(haproxy_base_dir, listener, cert.primary_cn) # build a string that represents the pem file to be saved pem = _build_pem(cert) n_utils.replace_file(cert_path, pem) return cert_path
def save_config(conf_path, loadbalancer, socket_path, user_group, haproxy_base_dir): """Convert a logical configuration to the HAProxy version. :param conf_path: location of Haproxy configuration :param loadbalancer: the load balancer object :param socket_path: location of haproxy socket data :param user_group: user group :param haproxy_base_dir: location of the instances state data """ config_str = render_loadbalancer_obj(loadbalancer, user_group, socket_path, haproxy_base_dir) n_utils.replace_file(conf_path, config_str)
def _generate_radvd_conf(self, router_ports): radvd_conf = utils.get_conf_file_name(self._agent_conf.ra_confs, self._router_id, 'radvd.conf', True) buf = six.StringIO() network_mtu = 0 for p in router_ports: subnets = p.get('subnets', []) v6_subnets = [ subnet for subnet in subnets if netaddr.IPNetwork(subnet['cidr']).version == 6 ] if not v6_subnets: continue ra_modes = {subnet['ipv6_ra_mode'] for subnet in v6_subnets} auto_config_prefixes = [ subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC or subnet['ipv6_ra_mode'] == constants.DHCPV6_STATELESS ] stateful_config_prefixes = [ subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.DHCPV6_STATEFUL ] interface_name = self._dev_name_helper(p['id']) slaac_subnets = [ subnet for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC ] dns_servers = list( iter_chain(*[ subnet['dns_nameservers'] for subnet in slaac_subnets if subnet.get('dns_nameservers') ])) if self._agent_conf.advertise_mtu: network_mtu = p.get('mtu', 0) buf.write('%s' % CONFIG_TEMPLATE.render( ra_modes=list(ra_modes), interface_name=interface_name, auto_config_prefixes=auto_config_prefixes, stateful_config_prefixes=stateful_config_prefixes, dns_servers=dns_servers[0:MAX_RDNSS_ENTRIES], n_const=n_const, constants=constants, min_rtr_adv_interval=self._agent_conf.min_rtr_adv_interval, max_rtr_adv_interval=self._agent_conf.max_rtr_adv_interval, network_mtu=int(network_mtu))) common_utils.replace_file(radvd_conf, buf.getvalue()) return radvd_conf
def main(): """Expected arguments: sys.argv[1] - The add/update/delete operation performed by the PD agent sys.argv[2] - The file where the new prefix should be written sys.argv[3] - The process ID of the L3 agent to be notified of this change """ operation = sys.argv[1] prefix_fname = sys.argv[2] agent_pid = sys.argv[3] prefix = os.getenv('PREFIX1', "::") if operation == "add" or operation == "update": utils.replace_file(prefix_fname, "%s/64" % prefix) elif operation == "delete": utils.replace_file(prefix_fname, "::/64") os.kill(int(agent_pid), signal.SIGUSR1)
def _output_addn_hosts_file(self): """Writes a dnsmasq compatible additional hosts file. The generated file is sent to the --addn-hosts option of dnsmasq, and lists the hosts on the network which should be resolved even if the dnsmaq instance did not give a lease to the host (see the `_output_hosts_file` method). Each line in this file is in the same form as a standard /etc/hosts file. """ buf = six.StringIO() for host_tuple in self._iter_hosts(): port, alloc, hostname, fqdn, no_dhcp, no_opts = host_tuple # It is compulsory to write the `fqdn` before the `hostname` in # order to obtain it in PTR responses. if alloc: buf.write("%s\t%s %s\n" % (alloc.ip_address, fqdn, hostname)) addn_hosts = self.get_conf_file_name("addn_hosts") common_utils.replace_file(addn_hosts, buf.getvalue()) return addn_hosts
def _output_init_lease_file(self): """Write a fake lease file to bootstrap dnsmasq. The generated file is passed to the --dhcp-leasefile option of dnsmasq. This is used as a bootstrapping mechanism to avoid NAKing active leases when a dhcp server is scheduled to another agent. Using a leasefile will also prevent dnsmasq from NAKing or ignoring renewals after a restart. Format is as follows: epoch-timestamp mac_addr ip_addr hostname client-ID """ filename = self.get_conf_file_name("leases") buf = six.StringIO() LOG.debug("Building initial lease file: %s", filename) # we make up a lease time for the database entry if self.conf.dhcp_lease_duration == -1: # Even with an infinite lease, a client may choose to renew a # previous lease on reboot or interface bounce so we should have # an entry for it. # Dnsmasq timestamp format for an infinite lease is 0. timestamp = 0 else: timestamp = int(time.time()) + self.conf.dhcp_lease_duration dhcp_enabled_subnet_ids = [s.id for s in self.network.subnets if s.enable_dhcp] for host_tuple in self._iter_hosts(): port, alloc, hostname, name, no_dhcp, no_opts = host_tuple # don't write ip address which belongs to a dhcp disabled subnet # or an IPv6 SLAAC/stateless subnet if no_dhcp or alloc.subnet_id not in dhcp_enabled_subnet_ids: continue ip_address = self._format_address_for_dnsmasq(alloc.ip_address) # all that matters is the mac address and IP. the hostname and # client ID will be overwritten on the next renewal. buf.write("%s %s %s * *\n" % (timestamp, port.mac_address, ip_address)) contents = buf.getvalue() common_utils.replace_file(filename, contents) LOG.debug("Done building initial lease file %s with contents:\n%s", filename, contents) return filename
def _generate_dibbler_conf(self, ex_gw_ifname, lla): dcwa = self.dibbler_client_working_area script_path = utils.get_conf_file_name(dcwa, 'notify', 'sh', True) buf = six.StringIO() buf.write('%s' % SCRIPT_TEMPLATE.render(prefix_path=self.prefix_path, l3_agent_pid=os.getpid())) common_utils.replace_file(script_path, buf.getvalue()) os.chmod(script_path, 0o744) dibbler_conf = utils.get_conf_file_name(dcwa, 'client', 'conf', False) buf = six.StringIO() buf.write( '%s' % CONFIG_TEMPLATE.render(enterprise_number=cfg.CONF.vendor_pen, va_id='0x%s' % self.converted_subnet_id, script_path='"%s/notify.sh"' % dcwa, interface_name='"%s"' % ex_gw_ifname, bind_address='%s' % lla)) common_utils.replace_file(dibbler_conf, buf.getvalue()) return dcwa
def _generate_dibbler_conf(self, ex_gw_ifname, lla): dcwa = self.dibbler_client_working_area script_path = utils.get_conf_file_name(dcwa, 'notify', 'sh', True) buf = six.StringIO() buf.write('%s' % SCRIPT_TEMPLATE.render( prefix_path=self.prefix_path, l3_agent_pid=os.getpid())) common_utils.replace_file(script_path, buf.getvalue()) os.chmod(script_path, 0o744) dibbler_conf = utils.get_conf_file_name(dcwa, 'client', 'conf', False) buf = six.StringIO() buf.write('%s' % CONFIG_TEMPLATE.render( enterprise_number=cfg.CONF.vendor_pen, va_id='0x%s' % self.converted_subnet_id, script_path='"%s/notify.sh"' % dcwa, interface_name='"%s"' % ex_gw_ifname, bind_address='%s' % lla)) common_utils.replace_file(dibbler_conf, buf.getvalue()) return dcwa
def test_replace_file_default_mode(self): file_mode = 0o644 utils.replace_file(self.file_name, self.data) self._verify_result(file_mode)
def _output_config_file(self): config_str = self.config.get_config_str() config_path = self.get_full_config_file_path('keepalived.conf') common_utils.replace_file(config_path, config_str) return config_path
def test_replace_file_custom_mode(self): file_mode = 0o722 utils.replace_file(self.file_name, self.data, file_mode) self._verify_result(file_mode)
def _write_map(self, name_to_id): buf = six.StringIO() for name, table_id in name_to_id.items(): buf.write("%s\t%s\n" % (table_id, name)) utils.replace_file(self._rt_tables_filename, buf.getvalue())
def interface_name(self, value): interface_file_path = self.get_conf_file_name("interface") common_utils.replace_file(interface_file_path, value)