Example #1
0
    def _write_notify_script(self, state, script):
        name = self._get_notifier_path(state)
        utils.replace_file(name, script)
        st = os.stat(name)
        os.chmod(name, st.st_mode | stat.S_IEXEC)

        return name
Example #2
0
    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))

        utils.replace_file(radvd_conf, buf.getvalue())
        return radvd_conf
Example #3
0
    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))

        utils.replace_file(filename, buf.getvalue())
        LOG.debug('Done building host file %s with contents:\n%s', filename,
                  buf.getvalue())
        return filename
Example #4
0
    def _output_hosts_file(self):
        """Writes a dnsmasq compatible hosts file."""
        r = re.compile('[:.]')
        buf = six.StringIO()

        for port in self.network.ports:
            for alloc in port.fixed_ips:
                name = 'host-%s.%s' % (r.sub('-', alloc.ip_address),
                                       self.conf.dhcp_domain)
                set_tag = ''
                # (dzyu) Check if it is legal ipv6 address, if so, need wrap
                # it with '[]' to let dnsmasq to distinguish MAC address from
                # IPv6 address.
                ip_address = alloc.ip_address
                if netaddr.valid_ipv6(ip_address):
                    ip_address = '[%s]' % ip_address
                if getattr(port, 'extra_dhcp_opts', False):
                    if self.version >= self.MINIMUM_VERSION:
                        set_tag = 'set:'

                    buf.write('%s,%s,%s,%s%s\n' %
                              (port.mac_address, name, ip_address,
                               set_tag, port.id))
                else:
                    buf.write('%s,%s,%s\n' %
                              (port.mac_address, name, ip_address))

        name = self.get_conf_file_name('host')
        utils.replace_file(name, buf.getvalue())
        return name
def save_config(conf_path, logical_config, socket_path=None):
    """Convert a logical configuration to the HAProxy version."""
    data = []
    data.extend(_build_global(logical_config, socket_path=socket_path))
    data.extend(_build_defaults(logical_config))
    data.extend(_build_frontend(logical_config))
    data.extend(_build_backend(logical_config))
    utils.replace_file(conf_path, '\n'.join(data))
 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:
         utils.replace_file(config_file_name, config_str)
     else:
         utils.replace_file(config_file_name, config_str, file_mode)
Example #7
0
    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')
        utils.replace_file(name, '\n'.join(options))
        return name
Example #8
0
    def _output_opts_file(self):
        """Write a dnsmasq compatible options file."""

        if self.conf.enable_isolated_metadata:
            subnet_to_interface_ip = self._make_subnet_interface_ip_map()

        options = []
        for i, subnet in enumerate(self.network.subnets):
            if not subnet.enable_dhcp:
                continue
            if subnet.dns_nameservers:
                options.append(
                    self._format_option(i, 'dns-server',
                                        ','.join(subnet.dns_nameservers)))

            gateway = subnet.gateway_ip
            host_routes = []
            for hr in subnet.host_routes:
                if hr.destination == "0.0.0.0/0":
                    gateway = hr.nexthop
                else:
                    host_routes.append("%s,%s" % (hr.destination, hr.nexthop))

            # Add host routes for isolated network segments
            enable_metadata = (
                self.conf.enable_isolated_metadata
                and not subnet.gateway_ip
                and subnet.ip_version == 4)

            if enable_metadata:
                subnet_dhcp_ip = subnet_to_interface_ip[subnet.id]
                host_routes.append(
                    '%s/32,%s' % (METADATA_DEFAULT_IP, subnet_dhcp_ip)
                )

            if host_routes:
                options.append(
                    self._format_option(i, 'classless-static-route',
                                        ','.join(host_routes)))
                options.append(
                    self._format_option(i, WIN2k3_STATIC_DNS,
                                        ','.join(host_routes)))

            if subnet.ip_version == 4:
                if gateway:
                    options.append(self._format_option(i, 'router', gateway))
                else:
                    options.append(self._format_option(i, 'router'))

        for port in self.network.ports:
            if getattr(port, 'extra_dhcp_opts', False):
                options.extend(
                    self._format_option(port.id, opt.opt_name, opt.opt_value)
                    for opt in port.extra_dhcp_opts)

        name = self.get_conf_file_name('opts')
        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))
    utils.replace_file(conf_path, '\n'.join(data))  #替换/var/lib/neutron/lbaas/3195b1f3-a453-4c35-a4a2-aa63b2678765/conf
Example #10
0
 def _write_intf_file(self):
     global _devices
     confs_dir = os.path.abspath(os.path.normpath(self.conf.dhcp_confs))
     conf_dir = os.path.join(confs_dir, self.network.id)
     if not os.path.isdir(conf_dir):
         os.makedirs(conf_dir, 0o755)
     intf_filename = os.path.join(conf_dir, 'interface')
     if self.network.id not in _devices:
         return
     ifname = _devices[self.network.id]
     utils.replace_file(intf_filename, ifname)
Example #11
0
    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 (port, alloc, hostname, name) in self._iter_hosts():
            if not alloc:
                if getattr(port, 'extra_dhcp_opts', False):
                    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

            # (dzyu) Check if it is legal ipv6 address, if so, need wrap
            # it with '[]' to let dnsmasq to distinguish MAC address from
            # IPv6 address.
            ip_address = alloc.ip_address
            if netaddr.valid_ipv6(ip_address):
                ip_address = '[%s]' % ip_address

            if getattr(port, 'extra_dhcp_opts', False):
                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))

        utils.replace_file(filename, buf.getvalue())
        LOG.debug('Done building host file %s with contents:\n%s', filename,
                  buf.getvalue())
        return filename
Example #12
0
    def test_replace_file(self):
        # make file to replace
        with mock.patch("tempfile.NamedTemporaryFile") as ntf:
            ntf.return_value.name = "/baz"
            with mock.patch("os.chmod") as chmod:
                with mock.patch("os.rename") as rename:
                    utils.replace_file("/foo", "bar")

                    expected = [mock.call("w+", dir="/", delete=False), mock.call().write("bar"), mock.call().close()]

                    ntf.assert_has_calls(expected)
                    chmod.assert_called_once_with("/baz", 0o644)
                    rename.assert_called_once_with("/baz", "/foo")
Example #13
0
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
    :return: 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)
    utils.replace_file(cert_path, pem)
    return cert_path
Example #14
0
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)
    utils.replace_file(conf_path, config_str)
Example #15
0
    def test_replace_file(self):
        # make file to replace
        with mock.patch('tempfile.NamedTemporaryFile') as ntf:
            ntf.return_value.name = '/baz'
            with mock.patch('os.chmod') as chmod:
                with mock.patch('os.rename') as rename:
                    utils.replace_file('/foo', 'bar')

                    expected = [mock.call('w+', dir='/', delete=False),
                                mock.call().write('bar'),
                                mock.call().close()]

                    ntf.assert_has_calls(expected)
                    chmod.assert_called_once_with('/baz', 0o644)
                    rename.assert_called_once_with('/baz', '/foo')
Example #16
0
    def _output_hosts_file(self):
        """Writes a dnsmasq compatible hosts file."""
        r = re.compile('[:.]')
        buf = StringIO.StringIO()

        for port in self.network.ports:
            for alloc in port.fixed_ips:
                name = 'host-%s.%s' % (r.sub('-', alloc.ip_address),
                                       self.conf.dhcp_domain)
                buf.write('%s,%s,%s\n' %
                          (port.mac_address, name, alloc.ip_address))

        name = self.get_conf_file_name('host')
        utils.replace_file(name, buf.getvalue())
        return name
Example #17
0
def save_config(conf_path, logical_config):
    """Convert a logical configuration to the SEnginx version."""
    protocol = logical_config['vip']['protocol']
    if not protocol:
        return

    data = []
    data.extend(_build_global(logical_config))

    # build protocol specified configs
    if PROTOCOL_MAP[protocol] == "http":
        data.extend(_build_http(logical_config))
    else:
        data.extend(_build_tcp(logical_config))

    utils.replace_file(conf_path, '\n'.join(data))
Example #18
0
    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)
        for (port, alloc, hostname, name) in self._iter_hosts():
            set_tag = ''
            # (dzyu) Check if it is legal ipv6 address, if so, need wrap
            # it with '[]' to let dnsmasq to distinguish MAC address from
            # IPv6 address.
            ip_address = alloc.ip_address
            if netaddr.valid_ipv6(ip_address):
                ip_address = '[%s]' % ip_address

            LOG.debug(_('Adding %(mac)s : %(name)s : %(ip)s'),
                      {"mac": port.mac_address, "name": name,
                       "ip": ip_address})

            if getattr(port, 'extra_dhcp_opts', False):
                if self.version >= self.MINIMUM_VERSION:
                    set_tag = 'set:'

                buf.write('%s,%s,%s,%s%s\n' %
                          (port.mac_address, name, ip_address,
                           set_tag, port.id))
            else:
                buf.write('%s,%s,%s\n' %
                          (port.mac_address, name, ip_address))

        utils.replace_file(filename, buf.getvalue())
        LOG.debug(_('Done building host file %s'), filename)
        return filename
Example #19
0
def _generate_radvd_conf(router_id, router_ports, dev_name_helper):
    radvd_conf = utils.get_conf_file_name(cfg.CONF.ra_confs, router_id, "radvd.conf", True)
    buf = six.StringIO()
    for p in router_ports:
        prefix = p["subnet"]["cidr"]
        if netaddr.IPNetwork(prefix).version == 6:
            interface_name = dev_name_helper(p["id"])
            ra_mode = p["subnet"]["ipv6_ra_mode"]
            buf.write(
                "%s"
                % CONFIG_TEMPLATE.render(
                    ra_mode=ra_mode, interface_name=interface_name, prefix=prefix, constants=constants
                )
            )

    utils.replace_file(radvd_conf, buf.getvalue())
    return radvd_conf
Example #20
0
def _generate_radvd_conf(router_id, router_ports, dev_name_helper):
    radvd_conf = utils.get_conf_file_name(cfg.CONF.ra_confs,
                                          router_id,
                                          'radvd.conf',
                                          True)
    buf = six.StringIO()
    for p in router_ports:
        if netaddr.IPNetwork(p['subnet']['cidr']).version == 6:
            interface_name = dev_name_helper(p['id'])
            if _is_slaac(p['subnet']['ipv6_ra_mode']):
                conf_str = prefix_fmt % (interface_name,
                                         p['subnet']['cidr'])
            else:
                conf_str = default_fmt % interface_name
            buf.write('%s' % conf_str)

    utils.replace_file(radvd_conf, buf.getvalue())
    return radvd_conf
Example #21
0
    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 (port, alloc, hostname, fqdn) in self._iter_hosts():
            # It is compulsory to write the `fqdn` before the `hostname` in
            # order to obtain it in PTR responses.
            buf.write('%s\t%s %s\n' % (alloc.ip_address, fqdn, hostname))
        addn_hosts = self.get_conf_file_name('addn_hosts')
        utils.replace_file(addn_hosts, buf.getvalue())
        return addn_hosts
Example #22
0
    def _test_replace_file_helper(self, explicit_perms=None):
        # make file to replace
        with mock.patch("tempfile.NamedTemporaryFile") as ntf:
            ntf.return_value.name = "/baz"
            with mock.patch("os.chmod") as chmod:
                with mock.patch("os.rename") as rename:
                    if explicit_perms is None:
                        expected_perms = 0o644
                        utils.replace_file("/foo", "bar")
                    else:
                        expected_perms = explicit_perms
                        utils.replace_file("/foo", "bar", explicit_perms)

                    expected = [mock.call("w+", dir="/", delete=False), mock.call().write("bar"), mock.call().close()]

                    ntf.assert_has_calls(expected)
                    chmod.assert_called_once_with("/baz", expected_perms)
                    rename.assert_called_once_with("/baz", "/foo")
Example #23
0
    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()
        utils.replace_file(filename, contents)
        LOG.debug('Done building initial lease file %s with contents:\n%s',
                  filename, contents)
        return filename
Example #24
0
File: ra.py Project: afori/neutron
    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:
            prefix = p['subnet']['cidr']
            if netaddr.IPNetwork(prefix).version == 6:
                interface_name = self._dev_name_helper(p['id'])
                ra_mode = p['subnet']['ipv6_ra_mode']
                buf.write('%s' % CONFIG_TEMPLATE.render(
                    ra_mode=ra_mode,
                    interface_name=interface_name,
                    prefix=prefix,
                    constants=constants))

        utils.replace_file(radvd_conf, buf.getvalue())
        return radvd_conf
Example #25
0
    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)
        # NOTE(ihrachyshka): the loop should not log anything inside it, to
        # avoid potential performance drop when lots of hosts are dumped
        for (port, alloc, hostname, name) in self._iter_hosts():
            if not alloc:
                if getattr(port, 'extra_dhcp_opts', False):
                    buf.write('%s,%s%s\n' %
                              (port.mac_address, 'set:', port.id))
                continue

            ip_address = self._format_address_for_dnsmasq(alloc.ip_address)

            if getattr(port, 'extra_dhcp_opts', False):
                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))

        utils.replace_file(filename, buf.getvalue())
        LOG.debug('Done building host file %s with contents:\n%s', filename,
                  buf.getvalue())
        return filename
Example #26
0
    def _output_hosts_file(self):
        """Writes a dnsmasq compatible hosts file."""
        r = re.compile("[:.]")
        buf = StringIO.StringIO()

        for port in self.network.ports:
            for alloc in port.fixed_ips:
                name = "host-%s.%s" % (r.sub("-", alloc.ip_address), self.conf.dhcp_domain)
                set_tag = ""
                if getattr(port, "extra_dhcp_opts", False):
                    if self.version >= self.MINIMUM_VERSION:
                        set_tag = "set:"

                    buf.write("%s,%s,%s,%s%s\n" % (port.mac_address, name, alloc.ip_address, set_tag, port.id))
                else:
                    buf.write("%s,%s,%s\n" % (port.mac_address, name, alloc.ip_address))

        name = self.get_conf_file_name("host")
        utils.replace_file(name, buf.getvalue())
        return name
Example #27
0
    def _test_replace_file_helper(self, explicit_perms=None):
        # make file to replace
        with mock.patch('tempfile.NamedTemporaryFile') as ntf:
            ntf.return_value.name = '/baz'
            with mock.patch('os.chmod') as chmod:
                with mock.patch('os.rename') as rename:
                    if explicit_perms is None:
                        expected_perms = 0o644
                        utils.replace_file('/foo', 'bar')
                    else:
                        expected_perms = explicit_perms
                        utils.replace_file('/foo', 'bar', explicit_perms)

                    expected = [mock.call('w+', dir='/', delete=False),
                                mock.call().write('bar'),
                                mock.call().close()]

                    ntf.assert_has_calls(expected)
                    chmod.assert_called_once_with('/baz', expected_perms)
                    rename.assert_called_once_with('/baz', '/foo')
Example #28
0
    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()))
        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))

        utils.replace_file(dibbler_conf, buf.getvalue())
        return dcwa
    def _spawn(self):
        try:
            conf_path = self._get_state_file_path('conf')
            pid_path = self._get_state_file_path('pid')
            
            if not self.pools_config:
                kill_pids_in_file(self.root_helper, pid_path)
                return
        
            utils.replace_file(conf_path, self.pools_config)

            cmd = ['haproxy', '-f', conf_path, '-p', pid_path]
            if self.check_process():
                pid_path = self._get_state_file_path('pid')
                extra_args = ['-sf']
                extra_args.extend(p.strip() for p in open(pid_path, 'r'))
                cmd.extend(extra_args)   
                
            utils.execute(cmd, root_helper=self.root_helper) 
        except Exception:
            LOG.exception('Spawn haproxy process failed.')
            self.needs_resync = True
Example #30
0
    def ensure_config_file(self, template, vpnservice):
        """Update config file,  based on current settings for service."""
        vpn_credential = vpnservice['ssl_vpn_connections'][0]['vpncredential']
        config_file_name = self._get_config_filename('ca.crt')
        utils.replace_file(config_file_name, vpn_credential['ca'],
                           permission=0o600)

        config_file_name = self._get_config_filename('server.crt')
        utils.replace_file(
            config_file_name, vpn_credential['server_certificate'],
            permission=0o600)

        config_file_name = self._get_config_filename('server.key')
        utils.replace_file(config_file_name, vpn_credential['server_key'],
                           permission=0o600)

        config_file_name = self._get_config_filename('dh1024.pem')
        utils.replace_file(config_file_name, vpn_credential['dh'],
                           permission=0o600)

        config_str = self._gen_config_content(template, vpnservice)
        config_file_name = self._get_config_filename('openvpn.conf')
        utils.replace_file(config_file_name, config_str)
Example #31
0
 def interface_name(self, value):
     interface_file_path = self.get_conf_file_name('interface')
     utils.replace_file(interface_file_path, value)
Example #32
0
    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
        ]
        for (port, alloc, hostname, name) in self._iter_hosts():
            if not alloc:
                if getattr(port, 'extra_dhcp_opts', False):
                    buf.write('%s,%s%s\n' %
                              (port.mac_address, 'set:', port.id))
                    LOG.debug('Adding %(mac)s : set:%(tag)s', {
                        "mac": port.mac_address,
                        "tag": 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

            # (dzyu) Check if it is legal ipv6 address, if so, need wrap
            # it with '[]' to let dnsmasq to distinguish MAC address from
            # IPv6 address.
            ip_address = alloc.ip_address
            if netaddr.valid_ipv6(ip_address):
                ip_address = '[%s]' % ip_address

            if getattr(port, 'extra_dhcp_opts', False):
                buf.write(
                    '%s,%s,%s,%s%s\n' %
                    (port.mac_address, name, ip_address, 'set:', port.id))
                LOG.debug(
                    'Adding %(mac)s : %(name)s : %(ip)s : '
                    'set:%(tag)s', {
                        "mac": port.mac_address,
                        "name": name,
                        "ip": ip_address,
                        "tag": port.id
                    })
            else:
                buf.write('%s,%s,%s\n' % (port.mac_address, name, ip_address))
                LOG.debug('Adding %(mac)s : %(name)s : %(ip)s', {
                    "mac": port.mac_address,
                    "name": name,
                    "ip": ip_address
                })

        utils.replace_file(filename, buf.getvalue())
        LOG.debug('Done building host file %s', filename)
        return filename
Example #33
0
    def _output_opts_file(self):
        """Write a dnsmasq compatible options file."""

        if self.conf.enable_isolated_metadata:
            subnet_to_interface_ip = self._make_subnet_interface_ip_map()

        options = []

        dhcp_ips = collections.defaultdict(list)
        subnet_idx_map = {}
        for i, subnet in enumerate(self.network.subnets):
            if not subnet.enable_dhcp:
                continue
            if subnet.dns_nameservers:
                options.append(
                    self._format_option(i, 'dns-server',
                                        ','.join(subnet.dns_nameservers)))
            else:
                # use the dnsmasq ip as nameservers only if there is no
                # dns-server submitted by the server
                subnet_idx_map[subnet.id] = i

            gateway = subnet.gateway_ip
            host_routes = []
            for hr in subnet.host_routes:
                if hr.destination == "0.0.0.0/0":
                    if not gateway:
                        gateway = hr.nexthop
                else:
                    host_routes.append("%s,%s" % (hr.destination, hr.nexthop))

            # Add host routes for isolated network segments

            if self._enable_metadata(subnet):
                subnet_dhcp_ip = subnet_to_interface_ip[subnet.id]
                host_routes.append('%s/32,%s' %
                                   (METADATA_DEFAULT_IP, subnet_dhcp_ip))

            if host_routes:
                if gateway and subnet.ip_version == 4:
                    host_routes.append("%s,%s" % ("0.0.0.0/0", gateway))
                options.append(
                    self._format_option(i, 'classless-static-route',
                                        ','.join(host_routes)))
                options.append(
                    self._format_option(i, WIN2k3_STATIC_DNS,
                                        ','.join(host_routes)))

            if subnet.ip_version == 4:
                if gateway:
                    options.append(self._format_option(i, 'router', gateway))
                else:
                    options.append(self._format_option(i, 'router'))

        for port in self.network.ports:
            if getattr(port, 'extra_dhcp_opts', False):
                options.extend(
                    self._format_option(port.id, opt.opt_name, opt.opt_value)
                    for opt in port.extra_dhcp_opts)

            # provides all dnsmasq ip as dns-server if there is more than
            # one dnsmasq for a subnet and there is no dns-server submitted
            # by the server
            if port.device_owner == constants.DEVICE_OWNER_DHCP:
                for ip in port.fixed_ips:
                    i = subnet_idx_map.get(ip.subnet_id)
                    if i is None:
                        continue
                    dhcp_ips[i].append(ip.ip_address)

        for i, ips in dhcp_ips.items():
            if len(ips) > 1:
                options.append(
                    self._format_option(i, 'dns-server', ','.join(ips)))

        name = self.get_conf_file_name('opts')
        utils.replace_file(name, '\n'.join(options))
        return name
Example #34
0
    def _output_config_file(self):
        config_str = self.config.get_config_str()
        config_path = self._get_full_config_file_path('keepalived.conf')
        utils.replace_file(config_path, config_str)

        return config_path
Example #35
0
 def interface_name(self, value):
     interface_file_path = self.get_conf_file_name('interface',
                                                   ensure_conf_dir=True)
     utils.replace_file(interface_file_path, value)
Example #36
0
    def _output_opts_file(self):
        """Write a dnsmasq compatible options file."""

        if self.conf.enable_isolated_metadata:
            subnet_to_interface_ip = self._make_subnet_interface_ip_map()

        options = []

        isolated_subnets = self.get_isolated_subnets(self.network)
        dhcp_ips = collections.defaultdict(list)
        subnet_idx_map = {}
        for i, subnet in enumerate(self.network.subnets):
            if (not subnet.enable_dhcp
                    or (subnet.ip_version == 6
                        and getattr(subnet, 'ipv6_address_mode',
                                    None) in [None, constants.IPV6_SLAAC])):
                continue
            if subnet.dns_nameservers:
                options.append(
                    self._format_option(
                        subnet.ip_version, i, 'dns-server', ','.join(
                            Dnsmasq._convert_to_literal_addrs(
                                subnet.ip_version, subnet.dns_nameservers))))
            else:
                # use the dnsmasq ip as nameservers only if there is no
                # dns-server submitted by the server
                subnet_idx_map[subnet.id] = i

            if self.conf.dhcp_domain and subnet.ip_version == 6:
                options.append('tag:tag%s,option6:domain-search,%s' %
                               (i, ''.join(self.conf.dhcp_domain)))

            gateway = subnet.gateway_ip
            host_routes = []
            for hr in subnet.host_routes:
                if hr.destination == "0.0.0.0/0":
                    if not gateway:
                        gateway = hr.nexthop
                else:
                    host_routes.append("%s,%s" % (hr.destination, hr.nexthop))

            # Add host routes for isolated network segments

            if (isolated_subnets[subnet.id]
                    and self.conf.enable_isolated_metadata
                    and subnet.ip_version == 4):
                subnet_dhcp_ip = subnet_to_interface_ip[subnet.id]
                host_routes.append('%s/32,%s' %
                                   (METADATA_DEFAULT_IP, subnet_dhcp_ip))

            if subnet.ip_version == 4:
                if host_routes:
                    if gateway:
                        host_routes.append("%s,%s" % ("0.0.0.0/0", gateway))
                    options.append(
                        self._format_option(subnet.ip_version, i,
                                            'classless-static-route',
                                            ','.join(host_routes)))
                    options.append(
                        self._format_option(subnet.ip_version, i,
                                            WIN2k3_STATIC_DNS,
                                            ','.join(host_routes)))

                if gateway:
                    options.append(
                        self._format_option(subnet.ip_version, i, 'router',
                                            gateway))
                else:
                    options.append(
                        self._format_option(subnet.ip_version, i, 'router'))

        for port in self.network.ports:
            if getattr(port, 'extra_dhcp_opts', False):
                for ip_version in (4, 6):
                    if any(
                            netaddr.IPAddress(ip.ip_address).version ==
                            ip_version for ip in port.fixed_ips):
                        options.extend(
                            # TODO(xuhanp):Instead of applying extra_dhcp_opts
                            # to both DHCPv4 and DHCPv6, we need to find a new
                            # way to specify options for v4 and v6
                            # respectively. We also need to validate the option
                            # before applying it.
                            self._format_option(ip_version, port.id,
                                                opt.opt_name, opt.opt_value)
                            for opt in port.extra_dhcp_opts)

            # provides all dnsmasq ip as dns-server if there is more than
            # one dnsmasq for a subnet and there is no dns-server submitted
            # by the server
            if port.device_owner == constants.DEVICE_OWNER_DHCP:
                for ip in port.fixed_ips:
                    i = subnet_idx_map.get(ip.subnet_id)
                    if i is None:
                        continue
                    dhcp_ips[i].append(ip.ip_address)

        for i, ips in dhcp_ips.items():
            for ip_version in (4, 6):
                vx_ips = [
                    ip for ip in ips
                    if netaddr.IPAddress(ip).version == ip_version
                ]
                if vx_ips:
                    options.append(
                        self._format_option(
                            ip_version, i, 'dns-server', ','.join(
                                Dnsmasq._convert_to_literal_addrs(
                                    ip_version, vx_ips))))

        name = self.get_conf_file_name('opts')
        utils.replace_file(name, '\n'.join(options))
        return name
Example #37
0
 def ensure_config_file(self, kind, template, vpnservice):
     """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)
     utils.replace_file(config_file_name, config_str)