コード例 #1
0
def configure_management():
    parser = argparse.ArgumentParser(
        description='Configure Management Interface'
    )
    parser.add_argument('mac_address', metavar='lladdr', type=str)
    parser.add_argument('ip_address', metavar='ipaddr', type=str)
    parser.add_argument('--mtu', metavar='mtu', type=int, default=1280)
    args = parser.parse_args()

    ip_addr = netaddr.IPNetwork(args.ip_address)

    mgr = ip.IPManager()

    for intf in mgr.get_interfaces():
        if args.mac_address == intf.lladdr:
            if not intf.is_up:
                mgr.up(intf)

            intf.mtu = args.mtu

            if ip_addr not in intf.addresses:
                if ip_addr.version == 6:
                    real_ifname = mgr.generic_to_host(intf.ifname)
                    utils.execute([
                        'sysctl',
                        '-w',
                        'net.ipv6.conf.%s.accept_dad=0' % real_ifname
                    ])

                intf.addresses.append(ip_addr)
                mgr.update_interface(intf)
                configure_ssh(ip_addr.ip)
                configure_gunicorn(ip_addr.ip)
        break
コード例 #2
0
def configure_management():
    parser = argparse.ArgumentParser(
        description='Configure Management Interface'
    )
    parser.add_argument('mac_address', metavar='lladdr', type=str)
    parser.add_argument('ip_address', metavar='ipaddr', type=str)
    parser.add_argument('--mtu', metavar='mtu', type=int, default=1280)
    args = parser.parse_args()

    ip_addr = netaddr.IPNetwork(args.ip_address)

    mgr = ip.IPManager()

    for intf in mgr.get_interfaces():
        if args.mac_address == intf.lladdr:
            if not intf.is_up:
                mgr.up(intf)

            intf.mtu = args.mtu

            if ip_addr not in intf.addresses:
                if ip_addr.version == 6:
                    real_ifname = mgr.generic_to_host(intf.ifname)
                    utils.execute([
                        'sysctl',
                        '-w',
                        'net.ipv6.conf.%s.accept_dad=0' % real_ifname
                    ])

                intf.addresses.append(ip_addr)
                mgr.update_interface(intf)
                configure_ssh(ip_addr.ip)
                configure_gunicorn(ip_addr.ip)
        break
コード例 #3
0
 def stop(self):
     """
     Stop the Strongswan daemon using the system provided init scripts.
     """
     try:
         utils.execute(['service', 'strongswan', 'stop'], self.root_helper)
     except:  # pragma no cover
         pass
コード例 #4
0
 def ensure_started(self):
     """
     Checks if the metadata service is started and starts it if it is
     determined to be stopped.
     """
     try:
         execute(['/etc/init.d/metadata', 'status'], self.root_helper)
     except:
         execute(['/etc/init.d/metadata', 'start'], self.root_helper)
コード例 #5
0
 def delete_all_config(self):
     """
     Deletes all the dnsmasq configuration files (in <CONF_DIR>) that end in
     .conf.
     """
     for f in os.listdir(CONF_DIR):
         if f.endswith('.conf'):
             utils.execute(
                 ['rm', '-f', os.path.join(CONF_DIR, f)], self.root_helper)
コード例 #6
0
 def ensure_started(self):
     """
     Checks if the metadata service is started and starts it if it is
     determined to be stopped.
     """
     try:
         execute(['service', 'metadata', 'status'], self.root_helper)
     except:
         execute(['service', 'metadata', 'start'], self.root_helper)
コード例 #7
0
 def restart(self):
     """
     Restarts the metadata service using the init script.
     """
     try:
         execute(['service', 'metadata', 'stop'], self.root_helper)
     except:
         # failure is ok here
         pass
     execute(['service', 'metadata', 'start'], self.root_helper)
コード例 #8
0
 def test_execute_exception(self):
     with mock.patch('subprocess.check_output') as co:
         co.side_effect = subprocess.CalledProcessError(
             1, ['command', 'with', 'args'],
             output='output text',
         )
         try:
             utils.execute(['command', 'with', 'args'])
         except RuntimeError as e:
             self.assertIn('output text', str(e))
コード例 #9
0
 def restart(self):
     """
     Restarts the metadata service using the init script.
     """
     try:
         execute(['/etc/init.d/metadata', 'stop'], self.root_helper)
     except:
         # failure is ok here
         pass
     execute(['/etc/init.d/metadata', 'start'], self.root_helper)
コード例 #10
0
 def test_execute_exception(self):
     with mock.patch('subprocess.check_output') as co:
         co.side_effect = subprocess.CalledProcessError(
             1,
             ['command', 'with', 'args'],
             output='output text',
         )
         try:
             utils.execute(['command', 'with', 'args'])
         except RuntimeError as e:
             self.assertIn('output text', str(e))
コード例 #11
0
    def get_rules(self):
        '''
        Return the output of `iptables` and `ip6tables`.
        This function is used by astara orchestrator -> HTTP as a test for
        "router aliveness".

        :rtype: str
        '''
        v4 = utils.execute(['iptables', '-L', '-n'])
        v6 = utils.execute(['ip6tables', '-L', '-n'])
        return v4 + v6
コード例 #12
0
    def update_hosts(self, config):
        mgt_addr = config.management_address

        if not mgt_addr:
            return

        config_data = [
            '127.0.0.1  localhost',
            '::1  localhost ip6-localhost ip6-loopback',
            '%s  %s' % (mgt_addr, config.hostname)
        ]
        utils.replace_file('/tmp/hosts', '\n'.join(config_data))
        utils.execute(['mv', '/tmp/hosts', '/etc/hosts'], self.root_helper)
コード例 #13
0
    def save_config(self, config):
        """
        Writes <config> to the metadata configuration file (<CONF_PATH>).

        :type config: astara_router.models.Configuration
        :param config: An astara_router.models.Configuration object containing
                       the configuration of metadata service.
        """
        config_data = build_config(config)

        replace_file('/tmp/metadata.conf',
                     json.dumps(config_data, sort_keys=True))
        execute(['mv', '/tmp/metadata.conf', CONF_PATH], self.root_helper)
コード例 #14
0
    def update_hosts(self, config):
        mgt_addr = config.management_address

        if not mgt_addr:
            return

        config_data = [
            '127.0.0.1  localhost',
            '::1  localhost ip6-localhost ip6-loopback',
            '%s  %s' % (mgt_addr, config.hostname)
        ]
        utils.replace_file('/tmp/hosts', '\n'.join(config_data))
        utils.execute(['mv', '/tmp/hosts', '/etc/hosts'], self.root_helper)
コード例 #15
0
    def save_config(self, config, if_map):
        """
        Writes config file for bird daemon.

        :type config: astara_router.models.Configuration
        :param config:
        :type if_map: dict
        :param if_map: A (dict) mapping of generic to physical hostname, e.g.:
                       {'ge0': 'eth0', 'ge1': 'eth1'}
        """
        config_data = build_config(config, if_map)

        utils.replace_file('/tmp/bird6.conf', config_data)
        utils.execute(['mv', '/tmp/bird6.conf', CONF_PATH], self.root_helper)
コード例 #16
0
ファイル: bird.py プロジェクト: dreamhost/astara-appliance
    def save_config(self, config, if_map):
        """
        Writes config file for bird daemon.

        :type config: astara_router.models.Configuration
        :param config:
        :type if_map: dict
        :param if_map: A (dict) mapping of generic to physical hostname, e.g.:
                       {'ge0': 'eth0', 'ge1': 'eth1'}
        """
        config_data = build_config(config, if_map)

        utils.replace_file('/tmp/bird6.conf', config_data)
        utils.execute(['mv', '/tmp/bird6.conf', CONF_PATH], self.root_helper)
コード例 #17
0
    def save_config(self, config):
        """
        Writes <config> to the metadata configuration file (<CONF_PATH>).

        :type config: astara_router.models.Configuration
        :param config: An astara_router.models.Configuration object containing
                       the configuration of metadata service.
        """
        config_data = build_config(config)

        replace_file(
            '/tmp/metadata.conf',
            json.dumps(config_data, sort_keys=True)
        )
        execute(['mv', '/tmp/metadata.conf', CONF_PATH], self.root_helper)
コード例 #18
0
ファイル: ping.py プロジェクト: Cloudxtreme/astara-appliance
    def do(self, ip):
        """
        Sends a single ICMP packet to <ip> using the systems ping utility.

        :type ip: str
        :param ip: The IP address to send ICMP packets to.
        :rtype: bool. If <ip> responds to the ICMP packet, returns True else,
                returns False
        """
        version = netaddr.IPAddress(ip).version
        args = ['-c', '1', ip]
        try:
            utils.execute([self.exe_map.get(version)] + args)
            return True
        except RuntimeError:
            return False
コード例 #19
0
ファイル: ping.py プロジェクト: dreamhost/astara-appliance
    def do(self, ip):
        """
        Sends a single ICMP packet to <ip> using the systems ping utility.

        :type ip: str
        :param ip: The IP address to send ICMP packets to.
        :rtype: bool. If <ip> responds to the ICMP packet, returns True else,
                returns False
        """
        version = netaddr.IPAddress(ip).version
        args = ['-c', '1', ip]
        try:
            utils.execute([self.exe_map.get(version)] + args)
            return True
        except RuntimeError:
            return False
コード例 #20
0
ファイル: ip.py プロジェクト: Cloudxtreme/astara-appliance
    def _delete_conntrack_state(self, ip):
        """
        Explicitly remove an IP from in-kernel connection tracking.

        :param ip: The IP address to remove
        :type ip: netaddr.IPAddress
        """

        # If no flow entries are deleted, `conntrack -D` will return 1
        try:
            utils.execute(['conntrack', '-D', '-d', str(ip)], self.root_helper)
        except RuntimeError:
            LOG.debug('Failed deleting ingress connection state of %s' % ip)
        try:
            utils.execute(['conntrack', '-D', '-q', str(ip)], self.root_helper)
        except RuntimeError:
            LOG.debug('Failed deleting egress connection state of %s' % ip)
コード例 #21
0
    def restart(self):
        '''
        Reload firewall rules via [netfilter/iptables]-persistent
        Note that at some point iptables-persistent merged into
        netfilter-persistent as a plugin, so use that instead if it is
        available
        '''
        _init = '/etc/init.d/%s-persistent'
        if os.path.isfile(_init % 'netfilter'):
            init = _init % 'netfilter'
        else:
            init = _init % 'iptables'

        utils.execute(
            [init, 'restart'],
            self.root_helper
        )
コード例 #22
0
    def reload(self):
        try:
            last_config_hash = utils.hash_file(self.CONFIG_FILE)
        except IOError:
            last_config_hash = None

        utils.replace_file('/tmp/keepalived.conf', self.config())
        utils.execute(
            ['mv', '/tmp/keepalived.conf', '/etc/keepalived/keepalived.conf'],
            self.root_helper)

        if utils.hash_file(self.CONFIG_FILE) == last_config_hash:
            return

        if self._is_running():
            self.sudo('keepalived', 'reload')
        else:
            self.sudo('keepalived', 'restart')
コード例 #23
0
ファイル: ip.py プロジェクト: Cloudxtreme/astara-appliance
    def disable_duplicate_address_detection(self, network):
        """
        Disabled duplicate address detection for a specific interface.

        :type network: astara.models.Network
        """
        # For non-external networks, duplicate address detection isn't
        # necessary (and it sometimes results in race conditions for services
        # that attempt to bind to addresses before they're ready).

        if network.network_type != network.TYPE_EXTERNAL:
            real_ifname = self.generic_to_host(network.interface.ifname)
            try:
                utils.execute([
                    'sysctl', '-w',
                    'net.ipv6.conf.%s.accept_dad=0' % real_ifname
                ], self.root_helper)
            except RuntimeError:
                LOG.debug('Failed to disable v6 dad on %s' % real_ifname)
コード例 #24
0
    def sudo(self, *args):
        """
        Executes command <args> with the specified flags through the
        root_helper facility (i.e. escalated privileges).

        :type args: tuple
        :param args: A command, and flags, to execute.
        :rtype: tuple
        """
        return utils.execute([self.EXECUTABLE] + list(args), self.root_helper)
コード例 #25
0
    def do(self, *args):
        """
        Executes command <args> with specified flags and without escalated
        privileges.

        :type args: tuple
        :param args: A command, and flags, to execute.
        :rtype: tuple
        """
        return utils.execute([self.EXECUTABLE] + list(args))
コード例 #26
0
ファイル: base.py プロジェクト: dreamhost/astara-appliance
    def sudo(self, *args):
        """
        Executes command <args> with the specified flags through the
        root_helper facility (i.e. escalated privileges).

        :type args: tuple
        :param args: A command, and flags, to execute.
        :rtype: tuple
        """
        return utils.execute([self.EXECUTABLE] + list(args), self.root_helper)
コード例 #27
0
ファイル: base.py プロジェクト: dreamhost/astara-appliance
    def do(self, *args):
        """
        Executes command <args> with specified flags and without escalated
        privileges.

        :type args: tuple
        :param args: A command, and flags, to execute.
        :rtype: tuple
        """
        return utils.execute([self.EXECUTABLE] + list(args))
コード例 #28
0
ファイル: dnsmasq.py プロジェクト: dreamhost/astara-appliance
    def update_network_dhcp_config(self, ifname, network):
        """
        Updates the dnsmasq.conf config, enabling dhcp configuration for nova
        networks that are mapped to tenants and disabling networks that do not
        map to tenants.

        :type ifname: str
        :param ifname:
        :type network:
        :param network:

        """
        if network.is_tenant_network:
            config_data = self._build_dhcp_config(ifname, network)
        else:
            config_data = self._build_disabled_config(ifname)

        file_path = os.path.join(CONF_DIR, '%s.conf' % ifname)
        utils.replace_file('/tmp/dnsmasq.conf', config_data)
        utils.execute(['mv', '/tmp/dnsmasq.conf', file_path], self.root_helper)
コード例 #29
0
    def update_network_dhcp_config(self, ifname, network):
        """
        Updates the dnsmasq.conf config, enabling dhcp configuration for nova
        networks that are mapped to tenants and disabling networks that do not
        map to tenants.

        :type ifname: str
        :param ifname:
        :type network:
        :param network:

        """
        if network.is_tenant_network:
            config_data = self._build_dhcp_config(ifname, network)
        else:
            config_data = self._build_disabled_config(ifname)

        file_path = os.path.join(CONF_DIR, '%s.conf' % ifname)
        utils.replace_file('/tmp/dnsmasq.conf', config_data)
        utils.execute(['mv', '/tmp/dnsmasq.conf', file_path], self.root_helper)
コード例 #30
0
    def restart(self):
        """
        Restarts dnsmasq service using the system provided init script.
        """
        try:
            utils.execute(['service', 'dnsmasq', 'stop'], self.root_helper)
        except:
            pass

        # dnsmasq can get confused on startup
        remaining = 5
        while remaining:
            remaining -= 1
            try:
                utils.execute(['service', 'dnsmasq', 'start'],
                              self.root_helper)
                return
            except Exception:
                if remaining <= 0:
                    raise
                time.sleep(1)
コード例 #31
0
ファイル: ip.py プロジェクト: dreamhost/astara-appliance
    def _delete_conntrack_state(self, ip):
        """
        Explicitly remove an IP from in-kernel connection tracking.

        :param ip: The IP address to remove
        :type ip: netaddr.IPAddress
        """

        # If no flow entries are deleted, `conntrack -D` will return 1
        try:
            utils.execute(['conntrack', '-D', '-d', str(ip)], self.root_helper)
        except RuntimeError:
            LOG.debug(
                'Failed deleting ingress connection state of %s' % ip
            )
        try:
            utils.execute(['conntrack', '-D', '-q', str(ip)], self.root_helper)
        except RuntimeError:
            LOG.debug(
                'Failed deleting egress connection state of %s' % ip
            )
コード例 #32
0
ファイル: ip.py プロジェクト: dreamhost/astara-appliance
    def disable_duplicate_address_detection(self, network):
        """
        Disabled duplicate address detection for a specific interface.

        :type network: astara.models.Network
        """
        # For non-external networks, duplicate address detection isn't
        # necessary (and it sometimes results in race conditions for services
        # that attempt to bind to addresses before they're ready).

        if network.network_type != network.TYPE_EXTERNAL:
            real_ifname = self.generic_to_host(network.interface.ifname)
            try:
                utils.execute([
                    'sysctl', '-w', 'net.ipv6.conf.%s.accept_dad=0'
                    % real_ifname
                ], self.root_helper)
            except RuntimeError:
                LOG.debug(
                    'Failed to disable v6 dad on %s' % real_ifname
                )
コード例 #33
0
 def send_gratuitous_arp_for_floating_ips(self, config, generic_to_host):
     """
     Send a gratuitous ARP for every Floating IP.
     :type config: astara_router.models.Configuration
     :param config: An astara_router.models.Configuration object containing
                    configuration information for the system's network
                    setup.
     :type generic_to_host: callable
     :param generic_to_host: A callable which translates a generic interface
                             name (e.g., "ge0") to a physical name (e.g.,
                             "eth0")
     """
     external_nets = filter(
         lambda n: n.network_type == Network.TYPE_EXTERNAL, config.networks)
     for net in external_nets:
         for fip in net.floating_ips:
             utils.execute([
                 'astara-gratuitous-arp',
                 generic_to_host(net.interface.ifname),
                 str(fip.floating_ip)
             ], self.root_helper)
コード例 #34
0
ファイル: dnsmasq.py プロジェクト: dreamhost/astara-appliance
    def restart(self):
        """
        Restarts dnsmasq service using the system provided init script.
        """
        try:
            utils.execute([RC_PATH, 'stop'], self.root_helper)
        except:
            pass

        # dnsmasq can get confused on startup
        remaining = 5
        while remaining:
            remaining -= 1
            try:
                utils.execute(
                    [RC_PATH, 'start'], self.root_helper
                )
                return
            except Exception:
                if remaining <= 0:
                    raise
                time.sleep(1)
コード例 #35
0
ファイル: arp.py プロジェクト: dreamhost/astara-appliance
 def send_gratuitous_arp_for_floating_ips(self, config, generic_to_host):
     """
     Send a gratuitous ARP for every Floating IP.
     :type config: astara_router.models.Configuration
     :param config: An astara_router.models.Configuration object containing
                    configuration information for the system's network
                    setup.
     :type generic_to_host: callable
     :param generic_to_host: A callable which translates a generic interface
                             name (e.g., "ge0") to a physical name (e.g.,
                             "eth0")
     """
     external_nets = filter(
         lambda n: n.network_type == Network.TYPE_EXTERNAL,
         config.networks
     )
     for net in external_nets:
         for fip in net.floating_ips:
             utils.execute([
                 'astara-gratuitous-arp',
                 generic_to_host(net.interface.ifname),
                 str(fip.floating_ip)
             ], self.root_helper)
コード例 #36
0
    def save_config(self, config):
        """
        Writes config file for strongswan daemon.

        :type config: astara_router.models.Configuration
        """

        env = jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_DIR))

        env.filters['strongswan'] = lambda v: STRONGSWAN_TRANSLATIONS.get(v, v)

        templates = ('ipsec.conf', 'ipsec.secrets')

        for template_name in templates:
            tmpl = env.get_template(template_name + '.j2')

            tmp = os.path.join('/tmp', template_name)
            utils.replace_file(tmp, tmpl.render(vpnservices=config.vpn))

        for template_name in templates:
            tmp = os.path.join('/tmp', template_name)
            etc = os.path.join('/etc', template_name)
            utils.execute(['mv', tmp, etc], self.root_helper)
コード例 #37
0
    def save_config(self, config, interface_map):
        '''
        Save iptables-persistent firewall rules to disk.

        :param config: The astara configuration to save to disk
        :type config: astara.rug.models.Configuration
        :param interface_map: A mapping of virtual ('ge0') to physical ('eth0')
                              interface names
        :type interface_map: dict
        '''
        rules = itertools.chain(
            self._build_filter_table(config),
            self._build_nat_table(config),
            self._build_mangle_table(config),
            self._build_raw_table(config)
        )

        for version, rules in zip((4, 6), itertools.tee(rules)):
            data = '\n'.join(map(
                str,
                [r for r in rules if getattr(r, 'for_v%s' % version)]
            ))

            # Map virtual interface names
            real_name = interface_map.get('ge0')[:-1]
            ifname_re = '\-(?P<flag>i|o)(?P<ws>[\s!])(?P<not>!?)(?P<if>ge)(?P<no>\d+)'  # noqa
            ifname_sub = r'-\g<flag>\g<ws>\g<not>%s\g<no>' % real_name
            data = re.sub(ifname_re, ifname_sub, data) + '\n'

            utils.replace_file('/tmp/ip%stables.rules' % version, data)

            utils.execute([
                'mv',
                '/tmp/ip%stables.rules' % version,
                '/etc/iptables/rules.v%s' % version
            ], self.root_helper)
コード例 #38
0
    def save_config(self, config, generic_to_host):
        """
        Renders template and writes to the conntrackd file

        :type config: astara_router.models.Configuration
        :param config: An astara_router.models.Configuration object containing
                       the ha_config configuration.
        :param generic_to_host: A callable used to resolve generic interface
                                name to system interface name.
        """

        mgt_interface = None
        for interface in config.interfaces:
            if interface.management:
                mgt_interface = interface
                break
        mgt_addr = mgt_interface.first_v6 or mgt_interface.first_v4
        ctxt = {
            'source_address': str(mgt_addr),
            'management_ip_version': mgt_addr.version,
            'destination_address': config.ha_config['peers'][0],
            'interface': generic_to_host(interface.ifname),
        }

        try:
            old_config_hash = utils.hash_file(self.CONFIG_FILE)
        except IOError:
            old_config_hash = None

        utils.replace_file('/tmp/conntrackd.conf',
                           self._config_templ.render(ctxt))
        utils.execute(['mv', '/tmp/conntrackd.conf', self.CONFIG_FILE],
                      self.root_helper)

        if old_config_hash != utils.hash_file(self.CONFIG_FILE):
            self._should_restart = True
コード例 #39
0
ファイル: bird.py プロジェクト: dreamhost/astara-appliance
 def restart(self):
     """
     Restart the BIRD daemon using the system provided init scripts.
     """
     try:
         utils.execute(['/etc/init.d/bird6', 'status'], self.root_helper)
     except:  # pragma no cover
         utils.execute(['/etc/init.d/bird6', 'start'], self.root_helper)
     else:  # pragma no cover
         utils.execute(['/etc/init.d/bird6', 'reload'], self.root_helper)
コード例 #40
0
 def restart(self):
     """
     Restart the BIRD daemon using the system provided init scripts.
     """
     try:
         utils.execute(['service', 'bird6', 'status'], self.root_helper)
     except:  # pragma no cover
         utils.execute(['service', 'bird6', 'start'], self.root_helper)
     else:  # pragma no cover
         utils.execute(['service', 'bird6', 'reload'], self.root_helper)
コード例 #41
0
 def test_execute_exception_real(self):
     try:
         utils.execute(['/bin/ls', '/no-such-directory'])
     except RuntimeError as e:
         self.assertIn('cannot access', str(e))
コード例 #42
0
ファイル: nginx.py プロジェクト: dreamhost/astara-appliance
 def restart(self):
     execute(['service', self.INIT, 'restart'], self.root_helper)
コード例 #43
0
 def test_execute_exception_real(self):
     try:
         utils.execute(['/bin/ls', '/no-such-directory'])
     except RuntimeError as e:
         self.assertIn('cannot access', str(e))
コード例 #44
0
 def restart(self):
     execute(['service', self.INIT, 'restart'], self.root_helper)
コード例 #45
0
 def update_hostname(self, config):
     self.sudo(config.hostname)
     utils.replace_file('/tmp/hostname', config.hostname)
     utils.execute(
         ['mv', '/tmp/hostname', '/etc/hostname'], self.root_helper
     )
コード例 #46
0
 def update_hostname(self, config):
     self.sudo(config.hostname)
     utils.replace_file('/tmp/hostname', config.hostname)
     utils.execute(['mv', '/tmp/hostname', '/etc/hostname'],
                   self.root_helper)