예제 #1
0
def get_config():
    tz = deepcopy(default_config_data)
    conf = Config()
    if conf.exists('system time-zone'):
        tz['name'] = conf.return_value('system time-zone')

    return tz
def get_config():
    conf = Config()
    conf.set_level("service broadcast-relay id")
    relay_id = conf.list_nodes("")
    relays = []

    for id in relay_id:
        interface_list = []
        address = conf.return_value("{0} address".format(id))
        description = conf.return_value("{0} description".format(id))
        port = conf.return_value("{0} port".format(id))

        # split the interface name listing and form a list
        if conf.exists("{0} interface".format(id)):
            intfs_names = conf.return_values("{0} interface".format(id))
            intfs_names = intfs_names.replace("'", "")
            intfs_names = intfs_names.split()
            for name in intfs_names:
                interface_list.append(name)

        relay = {
            "id": id,
            "address": address,
            "description": description,
            "interfaces": interface_list,
            "port": port
        }
        relays.append(relay)

    return relays
예제 #3
0
def get_config():
    lldp = deepcopy(default_config_data)
    conf = Config()
    if not conf.exists(base):
        return None
    else:
        lldp['options'] = get_options(conf)
        lldp['interface_list'] = get_interface_list(conf)
        lldp['location'] = get_location(conf)

        return lldp
예제 #4
0
def get_config():
    nat = deepcopy(default_config_data)
    conf = Config()

    # read in current nftable (once) for further processing
    tmp = cmd('nft -j list table raw')
    nftable_json = json.loads(tmp)

    # condense the full JSON table into a list with only relevand informations
    pattern = 'nftables[?rule].rule[?expr[].jump].{chain: chain, handle: handle, target: expr[].jump.target | [0]}'
    condensed_json = jmespath.search(pattern, nftable_json)

    if not conf.exists(['nat']):
        nat['helper_functions'] = 'remove'

        # Retrieve current table handler positions
        nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING',
                                           'VYATTA_CT_HELPER')
        nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING',
                                              'NAT_CONNTRACK')
        nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT',
                                           'VYATTA_CT_HELPER')
        nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT',
                                              'NAT_CONNTRACK')

        nat['deleted'] = True

        return nat

    # check if NAT connection tracking helpers need to be set up - this has to
    # be done only once
    if not get_handler(condensed_json, 'PREROUTING', 'NAT_CONNTRACK'):
        nat['helper_functions'] = 'add'

        # Retrieve current table handler positions
        nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING',
                                           'VYATTA_CT_IGNORE')
        nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING',
                                              'VYATTA_CT_PREROUTING_HOOK')
        nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT',
                                           'VYATTA_CT_IGNORE')
        nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT',
                                              'VYATTA_CT_OUTPUT_HOOK')

    # set config level for parsing in NAT configuration
    conf.set_level(['nat'])

    # use a common wrapper function to read in the source / destination
    # tree from the config - thus we do not need to replicate almost the
    # same code :-)
    for tgt in ['source', 'destination', 'nptv6']:
        nat[tgt] = parse_source_destination(conf, tgt)

    return nat
예제 #5
0
def get_config():
    regdom = deepcopy(default_config_data)
    conf = Config()
    base = ['system', 'wifi-regulatory-domain']

    # Check if interface has been removed
    if not conf.exists(base):
        regdom['deleted'] = True
        return regdom
    else:
        regdom['regdom'] = conf.return_value(base)

    return regdom
예제 #6
0
def verify(bridge):
    if bridge['dhcpv6_prm_only'] and bridge['dhcpv6_temporary']:
        raise ConfigError(
            'DHCPv6 temporary and parameters-only options are mutually exclusive!'
        )

    vrf_name = bridge['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    conf = Config()
    for intf in bridge['member']:
        # the interface must exist prior adding it to a bridge
        if intf['name'] not in interfaces():
            raise ConfigError(
                (f'Cannot add nonexistent interface "{intf["name"]}" '
                 f'to bridge "{bridge["intf"]}"'))

        if intf['name'] == 'lo':
            raise ConfigError(
                'Loopback interface "lo" can not be added to a bridge')

        # bridge members aren't allowed to be members of another bridge
        for br in conf.list_nodes('interfaces bridge'):
            # it makes no sense to verify ourself in this case
            if br == bridge['intf']:
                continue

            tmp = conf.list_nodes(f'interfaces bridge {br} member interface')
            if intf['name'] in tmp:
                raise ConfigError((
                    f'Cannot add interface "{intf["name"]}" to bridge '
                    f'"{bridge["intf"]}", it is already a member of bridge "{br}"!'
                ))

        # bridge members are not allowed to be bond members
        tmp = is_member(conf, intf['name'], 'bonding')
        if tmp:
            raise ConfigError(
                (f'Cannot add interface "{intf["name"]}" to bridge '
                 f'"{bridge["intf"]}", it is already a member of bond "{tmp}"!'
                 ))

        # bridge members must not have an assigned address
        if has_address_configured(conf, intf['name']):
            raise ConfigError(
                (f'Cannot add interface "{intf["name"]}" to bridge '
                 f'"{bridge["intf"]}", it has an address assigned!'))

    return None
예제 #7
0
def get_config():
    c = Config()
    interfaces = dict()
    for intf in c.list_effective_nodes('interfaces ethernet'):
        # skip interfaces that are disabled or is configured for dhcp
        check_disable = "interfaces ethernet {} disable".format(intf)
        check_dhcp = "interfaces ethernet {} address dhcp".format(intf)
        if c.exists_effective(check_disable):
            continue

        # get addresses configured on the interface
        intf_addresses = c.return_effective_values(
            "interfaces ethernet {} address".format(intf))
        interfaces[intf] = [addr.strip("'") for addr in intf_addresses]
    return interfaces
예제 #8
0
def get_config():
    opt = deepcopy(default_config_data)
    conf = Config()
    conf.set_level('system options')
    if conf.exists(''):
        if conf.exists('ctrl-alt-del-action'):
            opt['ctrl_alt_del'] = conf.return_value('ctrl-alt-del-action')

        opt['beep_if_fully_booted'] = conf.exists('beep-if-fully-booted')
        opt['reboot_on_panic'] = conf.exists('reboot-on-panic')

    return opt
예제 #9
0
def show_status():
    # Do nothing if service is not configured
    c = Config()
    if not c.exists_effective('service dns dynamic'):
        print("Dynamic DNS not configured")
        sys.exit(0)

    data = {
        'hosts': []
    }

    with open(cache_file, 'r') as f:
        for line in f:
            if line.startswith('#'):
                continue

            outp = {
                'host': '',
                'ip': '',
                'time': ''
            }

            if 'host=' in line:
                host = line.split('host=')[1]
                if host:
                    outp['host'] = host.split(',')[0]

            if 'ip=' in line:
                ip = line.split('ip=')[1]
                if ip:
                    outp['ip'] = ip.split(',')[0]

            if 'atime=' in line:
                atime = line.split('atime=')[1]
                if atime:
                    tmp = atime.split(',')[0]
                    outp['time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(tmp, base=10)))

            if 'status=' in line:
                status = line.split('status=')[1]
                if status:
                    outp['status'] = status.split(',')[0]

            data['hosts'].append(outp)

    tmpl = jinja2.Template(OUT_TMPL_SRC)
    print(tmpl.render(data))
예제 #10
0
def get_config():
    """Get configuration"""
    conf = Config()

    hostname = conf.return_value("system host-name")
    domain = conf.return_value("system domain-name")

    # No one likes fixups, but we really don't want VyOS fail to boot
    # if hostname is not in the config
    if not hostname:
        hostname = "vyos"

    if domain:
        fqdn = "{0}.{1}".format(hostname, domain)
    else:
        fqdn = hostname

    return {"hostname": hostname, "domain": domain, "fqdn": fqdn}
예제 #11
0
def get_config():
    ip_opt = deepcopy(default_config_data)
    conf = Config()
    conf.set_level('system ip')
    if conf.exists(''):
        if conf.exists('arp table-size'):
            ip_opt['arp_table'] = int(conf.return_value('arp table-size'))

        if conf.exists('disable-forwarding'):
            ip_opt['ipv4_forward'] = '0'

        if conf.exists('multipath ignore-unreachable-nexthops'):
            ip_opt['mp_unreach_nexthop'] = '1'

        if conf.exists('multipath layer4-hashing'):
            ip_opt['mp_layer4_hashing'] = '1'

    return ip_opt
예제 #12
0
def get_config():
  c = Config()
  config_data = {
    'qat_conf'     : None,
    'ipsec_conf'   : None,
    'openvpn_conf' : None,
  }

  if c.exists('system acceleration qat'):
    config_data['qat_conf'] = True

  if c.exists('vpn ipsec '):
    gl_ipsec_conf = True
    config_data['ipsec_conf'] = True

  if c.exists('interfaces openvpn'):
    config_data['openvpn_conf'] = True

  return config_data
예제 #13
0
def list_users():
    cfg = Config()
    vyos_users = cfg.list_effective_nodes('system login user')
    users = []
    with open('/var/log/lastlog', 'rb') as lastlog_file:
        for (name, _, uid, _, _, _, _) in pwd.getpwall():
            lastlog_info = decode_lastlog(lastlog_file, uid)
            if lastlog_info is None:
                continue
            user_info = UserInfo(
                uid,
                name,
                user_type='vyos' if name in vyos_users else 'other',
                is_locked=is_locked(name),
                login_time=lastlog_info[0],
                tty=lastlog_info[1],
                host=lastlog_info[2])
            users.append(user_info)
    return users
예제 #14
0
def get_config():
    conf = Config()
    if not conf.exists('service https certificates certbot'):
        return None
    else:
        conf.set_level('service https certificates certbot')

    cert = {}

    if conf.exists('domain-name'):
        cert['domains'] = conf.return_values('domain-name')

    if conf.exists('email'):
        cert['email'] = conf.return_value('email')

    return cert
예제 #15
0
def get_config():
    bgp = deepcopy(default_config_data)
    conf = Config()

    # this lives in the "nbgp" tree until we switch over
    base = ['protocols', 'nbgp']
    if not conf.exists(base):
        return None

    bgp = deepcopy(default_config_data)
    # Get full BGP configuration as dictionary - output the configuration for development
    #
    # vyos@vyos# commit
    # [ protocols nbgp 65000 ]
    # {'nbgp': {'65000': {'address-family': {'ipv4-unicast': {'aggregate-address': {'1.1.0.0/16': {},
    #                                                                               '2.2.2.0/24': {}}},
    #                                        'ipv6-unicast': {'aggregate-address': {'2001:db8::/32': {}}}},
    #                     'neighbor': {'192.0.2.1': {'password': '******',
    #                                                'remote-as': '100'}}}}}
    #
    tmp = conf.get_config_dict(base)

    # extract base key from dict as this is our AS number
    bgp['as_number'] = jmespath.search('nbgp | keys(@) [0]', tmp)

    # adjust level of dictionary returned by get_config_dict()
    # by using jmesgpath and update dictionary
    bgp.update(jmespath.search('nbgp.* | [0]', tmp))

    from pprint import pprint
    pprint(bgp)
    # resulting in e.g.
    # vyos@vyos# commit
    # [ protocols nbgp 65000 ]
    # {'address-family': {'ipv4-unicast': {'aggregate-address': {'1.1.0.0/16': {},
    #                                                            '2.2.2.0/24': {}}},
    #                     'ipv6-unicast': {'aggregate-address': {'2001:db8::/32': {}}}},
    #  'as_number': '65000',
    #  'neighbor': {'192.0.2.1': {'password': '******', 'remote-as': '100'}},
    #  'timers': {'holdtime': '5'}}

    return bgp
예제 #16
0
def get_config():
    conf = Config()
    options = get_options(conf)
    interface_list = get_interface_list(conf)
    location = get_location(conf)
    lldp = {
        "options": options,
        "interface_list": interface_list,
        "location": location
    }
    return lldp
예제 #17
0
def verify(eth):
    if eth['deleted']:
        return None

    if eth['intf'] not in interfaces():
        raise ConfigError(f"Interface ethernet {eth['intf']} does not exist")

    if eth['speed'] == 'auto':
        if eth['duplex'] != 'auto':
            raise ConfigError(
                'If speed is hardcoded, duplex must be hardcoded, too')

    if eth['duplex'] == 'auto':
        if eth['speed'] != 'auto':
            raise ConfigError(
                'If duplex is hardcoded, speed must be hardcoded, too')

    if eth['dhcpv6_prm_only'] and eth['dhcpv6_temporary']:
        raise ConfigError(
            'DHCPv6 temporary and parameters-only options are mutually exclusive!'
        )

    vrf_name = eth['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    conf = Config()
    # some options can not be changed when interface is enslaved to a bond
    for bond in conf.list_nodes('interfaces bonding'):
        if conf.exists('interfaces bonding ' + bond + ' member interface'):
            bond_member = conf.return_values('interfaces bonding ' + bond +
                                             ' member interface')
            if eth['intf'] in bond_member:
                if eth['address']:
                    raise ConfigError(
                        f"Can not assign address to interface {eth['intf']} which is a member of {bond}"
                    )

    # use common function to verify VLAN configuration
    verify_vlan_config(eth)
    return None
예제 #18
0
def generate(c):
    c_eff = Config()
    c_eff.set_level('protocols static')
    c_eff_cnf = {}
    for ip_addr in c_eff.list_effective_nodes('arp'):
        c_eff_cnf.update({
            ip_addr:
            c_eff.return_effective_value('arp ' + ip_addr + ' hwaddr')
        })

    config_data = {'remove': [], 'update': {}}
    ### removal
    if c == None:
        for ip_addr in c_eff_cnf:
            config_data['remove'].append(ip_addr)
    else:
        for ip_addr in c_eff_cnf:
            if not ip_addr in c or c[ip_addr] == None:
                config_data['remove'].append(ip_addr)

    ### add/update
    if c != None:
        for ip_addr in c:
            if not ip_addr in c_eff_cnf:
                config_data['update'][ip_addr] = c[ip_addr]
            if ip_addr in c_eff_cnf:
                if c[ip_addr] != c_eff_cnf[ip_addr] and c[ip_addr] != None:
                    config_data['update'][ip_addr] = c[ip_addr]

    return config_data
예제 #19
0
def get_config():
    c = Config()
    if not c.exists('protocols static arp'):
        return None

    c.set_level('protocols static')
    config_data = {}

    for ip_addr in c.list_nodes('arp'):
        config_data.update(
            {ip_addr: c.return_value('arp ' + ip_addr + ' hwaddr')})

    return config_data
예제 #20
0
def get_config():
    bfd = deepcopy(default_config_data)
    conf = Config()
    if not (conf.exists('protocols bfd')
            or conf.exists_effective('protocols bfd')):
        return None
    else:
        conf.set_level('protocols bfd')

    # as we have to use vtysh to talk to FRR we also need to know
    # which peers are gone due to a config removal - thus we read in
    # all peers (active or to delete)
    for peer in conf.list_effective_nodes('peer'):
        bfd['old_peers'].append(get_bfd_peer_config(peer, "effective"))

    for peer in conf.list_nodes('peer'):
        bfd['new_peers'].append(get_bfd_peer_config(peer))

    # find deleted peers
    set_new_peers = set(conf.list_nodes('peer'))
    set_old_peers = set(conf.list_effective_nodes('peer'))
    bfd['deleted_peers'] = set_old_peers - set_new_peers

    return bfd
예제 #21
0
def show_brief():
    config = Config()
    if len(config.list_effective_nodes('interfaces wireless')) == 0:
        print("No Wireless interfaces configured")
        exit(0)

    interfaces = []
    for intf in config.list_effective_nodes('interfaces wireless'):
        config.set_level('interfaces wireless {}'.format(intf))
        data = {'name': intf, 'type': '', 'ssid': '', 'channel': ''}
        data['type'] = config.return_effective_value('type')
        data['ssid'] = config.return_effective_value('ssid')
        data['channel'] = config.return_effective_value('channel')

        interfaces.append(data)

    return interfaces
예제 #22
0
def get_config():
    conf = Config()
    conf.set_level("system task-scheduler task")
    task_names = conf.list_nodes("")
    tasks = []

    for name in task_names:
        interval = conf.return_value("{0} interval".format(name))
        spec = conf.return_value("{0} crontab-spec".format(name))
        executable = conf.return_value("{0} executable path".format(name))
        args = conf.return_value("{0} executable arguments".format(name))
        task = {
            "name": name,
            "interval": interval,
            "spec": spec,
            "executable": executable,
            "args": args
        }
        tasks.append(task)

    return tasks
예제 #23
0
def get_config():
    banner = default_config_data
    conf = Config()
    base_level = ['system', 'login', 'banner']

    if not conf.exists(base_level):
        return banner
    else:
        conf.set_level(base_level)

    # Post-Login banner
    if conf.exists(['post-login']):
        tmp = conf.return_value(['post-login'])
        # post-login banner can be empty as well
        if tmp:
            tmp = tmp.replace('\\n', '\n')
            tmp = tmp.replace('\\t', '\t')
            # always add newline character
            tmp += '\n'
        else:
            tmp = ''

        banner['motd'] = tmp

    # Pre-Login banner
    if conf.exists(['pre-login']):
        tmp = conf.return_value(['pre-login'])
        # pre-login banner can be empty as well
        if tmp:
            tmp = tmp.replace('\\n', '\n')
            tmp = tmp.replace('\\t', '\t')
            # always add newline character
            tmp += '\n'
        else:
            tmp = ''

        banner['issue'] = banner['issue_net'] = tmp

    return banner
예제 #24
0
def get_config():
    mdns = deepcopy(default_config_data)
    conf = Config()
    base = ['service', 'mdns', 'repeater']
    if not conf.exists(base):
        return None
    else:
        conf.set_level(base)

    # Service can be disabled by user
    if conf.exists(['disable']):
        mdns['disabled'] = True
        return mdns

    # Interface to repeat mDNS advertisements
    if conf.exists(['interface']):
        mdns['interfaces'] = conf.return_values(['interface'])

    return mdns
예제 #25
0
def get_config():
    interface_list = []

    conf = Config()
    conf.set_level('service mdns repeater')
    if not conf.exists(''):
        return interface_list

    if conf.exists('interface'):
        intfs_names = []
        intfs_names = conf.return_values('interface')

        for name in intfs_names:
            interface_list.append(name)

    return interface_list
예제 #26
0
def get_config():
    vyos_cert = vyos.defaults.vyos_cert_data

    conf = Config()
    if not conf.exists(
            'service https certificates system-generated-certificate'):
        return None
    else:
        conf.set_level(
            'service https certificates system-generated-certificate')

    if conf.exists('lifetime'):
        lifetime = conf.return_value('lifetime')
        vyos_cert['lifetime'] = lifetime

    return vyos_cert
예제 #27
0
def verify(bridge):
    if bridge['dhcpv6_prm_only'] and bridge['dhcpv6_temporary']:
        raise ConfigError(
            'DHCPv6 temporary and parameters-only options are mutually exclusive!'
        )

    vrf_name = bridge['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    conf = Config()
    for br in conf.list_nodes('interfaces bridge'):
        # it makes no sense to verify ourself in this case
        if br == bridge['intf']:
            continue

        for intf in bridge['member']:
            tmp = conf.list_nodes(
                'interfaces bridge {} member interface'.format(br))
            if intf['name'] in tmp:
                raise ConfigError(
                    'Interface "{}" belongs to bridge "{}" and can not be enslaved.'
                    .format(intf['name'], bridge['intf']))

    # the interface must exist prior adding it to a bridge
    for intf in bridge['member']:
        if intf['name'] not in interfaces():
            raise ConfigError(
                'Can not add non existing interface "{}" to bridge "{}"'.
                format(intf['name'], bridge['intf']))

        if intf['name'] == 'lo':
            raise ConfigError(
                'Loopback interface "lo" can not be added to a bridge')

    # bridge members are not allowed to be bond members, too
    for intf in bridge['member']:
        for bond in conf.list_nodes('interfaces bonding'):
            if conf.exists('interfaces bonding ' + bond + ' member interface'):
                if intf['name'] in conf.return_values('interfaces bonding ' +
                                                      bond +
                                                      ' member interface'):
                    raise ConfigError(
                        'Interface {} belongs to bond {}, can not add it to {}'
                        .format(intf['name'], bond, bridge['intf']))

    return None
예제 #28
0
def get_config():
    c = Config()
    if not c.exists_effective('interfaces ethernet'):
        return None

    interfaces = {}
    for intf in c.list_effective_nodes('interfaces ethernet'):
        if not c.exists_effective('interfaces ethernet ' + intf +
                                  ' disable') and c.exists_effective(
                                      'interfaces ethernet ' + intf +
                                      ' address'):
            interfaces[intf] = re.sub(
                "\'", "",
                c.return_effective_values('interfaces ethernet ' + intf +
                                          ' address')).split()

    return interfaces
예제 #29
0
def get_config():
    http_api = deepcopy(vyos.defaults.api_data)
    x = http_api.get('api_keys')
    if x is None:
        default_key = None
    else:
        default_key = x[0]
    keys_added = False

    conf = Config()
    if not conf.exists('service https api'):
        return None
    else:
        conf.set_level('service https api')

    if conf.exists('strict'):
        http_api['strict'] = 'true'

    if conf.exists('debug'):
        http_api['debug'] = 'true'

    if conf.exists('port'):
        port = conf.return_value('port')
        http_api['port'] = port

    if conf.exists('keys'):
        for name in conf.list_nodes('keys id'):
            if conf.exists('keys id {0} key'.format(name)):
                key = conf.return_value('keys id {0} key'.format(name))
                new_key = {'id': name, 'key': key}
                http_api['api_keys'].append(new_key)
                keys_added = True

    if keys_added and default_key:
        if default_key in http_api['api_keys']:
            http_api['api_keys'].remove(default_key)

    return http_api
예제 #30
0
    {% endfor %}{% endif %}
"""

VIEW_OUTP_TMPL_SRC = """
SNMPv3 Views:
    {% if view -%}{% for v in view %}
    View : {{ v.name }}
    OIDs : .{{ v.oids | join("\n           .")}}
    {% endfor %}{% endif %}
"""

if __name__ == '__main__':
    args = parser.parse_args()

    # Do nothing if service is not configured
    c = Config()
    if not c.exists_effective('service snmp v3'):
        print("SNMP v3 is not configured")
        sys.exit(0)

    data = {
        'group': [],
        'trap': [],
        'user': [],
        'view': []
    }
    
    if c.exists_effective('service snmp v3 group'):
        for g in c.list_effective_nodes('service snmp v3 group'):
            group = {
                'name': g,