Exemplo n.º 1
0
def generate(host, *args):

    ircds = sorted(lib.get_nodes_with_package('ircd', 'event').keys())

    info = {}
    if ircds:
        info['ircserver'] = ircds[0]
    info['admins'] = sorted(grp.getgrnam('ircbot-admin-access').gr_mem)

    return {'ircbot': info}
Exemplo n.º 2
0
def generate(host, *args):

    my_domain = lib.get_domain(host)
    ldap_servers = sorted(lib.get_nodes_with_package('ldap', my_domain).keys())

    # Just pick the first LDAP server (lexographically)
    server = ldap_servers[0]
    info = {}
    if 'ldap' in args:
        info['ldap'] = server
    return {'apache': info}
Exemplo n.º 3
0
def generate(host, *args):

    ircbots = sorted(lib.get_nodes_with_package('ircbot', 'event').keys())

    info = {}
    if 'rsyslog' in args:
        if ircbots:
            info['rsyslog'] = {'ircbot': ircbots[0]}
        else:
            info['rsyslog'] = {}

    return info
Exemplo n.º 4
0
def generate(host, *args):

    info = {}
    info['etcd::install'] = {}
    variant = args[0]
    etcd = []
    for h, o in lib.get_nodes_with_package("etcd").items():
        if variant in o:
            etcd.append(h)
    if len(etcd) == 0:
        raise Exception("cannot create single node etcd cluster")
    info['etcd::init'] = {'variant': variant, 'nodes': etcd}

    return info
Exemplo n.º 5
0
def generate(host, *args):
    role = args[0]
    ircds = lib.get_nodes_with_package('ircd')
    peers = list()
    for ircd in ircds:
        if role in ircds[ircd]:
            continue
        v4 = lib.resolve_nodes_to_ip((ircd, ))[ircd][0]
        peer = dict()
        peer['fqdn'] = ircd
        peer['allowmask'] = v4 + "/32"
        peers.append(peer)
    info = {}
    info['peers'] = peers
    info['sid'] = args[1]
    return {'inspircd': info}
Exemplo n.º 6
0
def generate(host, *args):
    my_environment = lib.get_environment(host)
    masters = sorted(lib.get_nodes_with_package('puppetmaster').keys())

    # Do not install client agent files on master, it's managed by SVN instead
    if host in masters:
        return {}

    ipv4, _ = lib.resolve_nodes_to_ip((host, ))[host]

    info = {}
    info['sourceaddress'] = ipv4
    info['master'] = sorted(masters)[0]
    info['environment'] = my_environment

    return {'puppet': info}
Exemplo n.º 7
0
def generate(host, *args):

    current_event = lib.get_current_event()
    info = {}
    info['kubernetes::install'] = {}

    if 'colo' in args:
        info['colo_k8s'] = {}
    else:
        variant = args[1]
        if 'worker' in args:
            # find api server that maches the variant
            apiserver = ""
            for h, o in lib.get_nodes_with_package("kubernetes").items():
                if "control" in o and variant in o:
                    apiserver = h
            if apiserver == "":
                raise Exception("k8s apiserver missing in ipplan")
            secretpath = '{}-services/kube-{}:token'.format(
                current_event, variant)
            secrets = lib.read_secret(secretpath)
            if not secrets:
                raise Exception(
                    "Kubeadm token secret missing. Is master deployed?")
            info['kubernetes::worker'] = {
                'variant': variant,
                'apiserver': apiserver,
                'cert_hash': secrets['cert_hash'],
                'token': secrets['token']
            }
        if 'control' in args:
            servicenet = lib.match_networks_name("EVENT@" + variant.upper() +
                                                 ".*K8S-SVC")
            podnet = lib.match_networks_name("EVENT@" + variant.upper() +
                                             ".*K8S-POD")
            if len(servicenet) == 0 or len(podnet) == 0:
                raise Exception("service- and/or podnet not found in ipplan")
            info['kubernetes::master'] = {
                'variant': variant,
                'podnet': podnet[0],
                'servicenet': servicenet[0],
                'current_event': current_event
            }

    return info
Exemplo n.º 8
0
def generate(host, *args):
    """Generate ldaplogin information.

    Args:
      *args: list(str): list of groups allowed to log in in addition to the
          default users.
      special keywords:
        - git: restrict non-sudo users to git-shell
        - otp: allow use of otp
        - [0-9]+: listen on given port
    """
    my_domain = lib.get_domain(host)
    ldap_servers = lib.get_nodes_with_package('ldap', my_domain)
    ldap_replicas = sorted(k for k, v in ldap_servers.iteritems()
                           if 'master' not in v)

    # We want to be able to mutate the list
    args = list(args)

    if not ldap_replicas:
        # If we don't have any LDAP servers, don't include this module
        return {}

    # We're only using the lowest two parts of the FQDN for identity.
    # LDAP doesn't allow period in group names, replace with slash.
    ident = '-'.join(host.split('.')[0:2])

    info = {}

    # 'otp' is a special keyword to enable otp authentication on the host
    if 'otp' in args:
        args.remove('otp')
        info['use_otp'] = True

    # find numbers in args, use it for ports
    # 22 used by default, 2022 used for jumpgates
    info['ssh_ports'] = set([22, 2022])
    for arg in args:
        if re.match('^[0-9]+$', arg):
            info['ssh_ports'].add(int(arg))
            args.remove(arg)
    info['ssh_ports'] = list(info['ssh_ports'])

    # For sudo users we have two groups:
    # For event: services-event
    # For colo: services-colo
    # (.. and the ident-sudo group)
    info['sudo'] = [ident + '-sudo-access']
    services_group = 'services-colo-team'
    if my_domain == 'EVENT':
        services_group = 'services-team'
    info['sudo'].append(services_group)

    groups = []
    for arg in args:
        if arg.startswith('sudo'):
            _, group = arg.split(':', 2)
            info['sudo'].append(group)
        else:
            groups.append(arg)

    # 'git' is a special keyword to enable restricting users to git-shell
    if 'git' in args:
        args.remove('git')
        info['gitshell'] = ','.join(['!' + x for x in info['sudo']]) + ',*'

    # Who should be allowed to log in to this system?
    info['logon'] = [
        (ident + '-access', 'ALL EXCEPT LOCAL'),
    ]

    # Allow sudo users to logon everywhere
    for group in info['sudo']:
        info['logon'].append((group, 'ALL'))

    # Add all explicit groups
    for group in groups:
        # Allow local logins as well to allow scripts to auth users
        formatted = group.format(event=lib.get_current_event())
        info['logon'].append((formatted, 'ALL'))

    # LDAP settings
    info['ldap'] = {'servers': [], 'servers_ip': {}}

    for server in ldap_replicas:
        info['ldap']['servers'].append(server)
        (server_ipv4, server_ipv6), = lib.resolve_nodes_to_ip([server
                                                               ]).values()
        info['ldap']['servers_ip'][server] = (server_ipv4, server_ipv6)

    info['ldap']['base'] = 'dc=tech,dc=dreamhack,dc=se'
    info['ldap']['mount'] = '/ldap'
    info['ca'] = lib.read_secret('ssh/config/ca')['public_key']
    info['host_cert'] = sign_host_key(host)
    info['panic_users'] = sorted(grp.getgrnam(services_group).gr_mem)
    generate_borg_passphrase(host)

    return {'ldaplogin': info}
Exemplo n.º 9
0
def generate(host, *args):

    # Decide if we are the active node:
    if 'active' in args:
        active = 1
    else:
        active = 0

    # Get fqdn of active node
    active_node = 'dhcp1.event.dreamhack.se'
    for (k, v) in lib.get_nodes_with_package('dhcpd',
                                             lib.get_domain(host)).items():
        if v == [u'active']:
            active_node = k
            break

    # Fetch DHCP scopes
    scopes = lib.sqlite2dhcp_scope.App(['-', '/etc/ipplan.db',
                                        '-']).run_from_puppet()

    # Get the subnet the dhcpd lives at in CIDR notation
    local_subnet_cidr = lib.get_ipv4_network(host)[0]
    local_subnet = local_subnet_cidr.split('/')[0]
    local_cidr = int(local_subnet_cidr.split('/')[1])

    # Convert CIDR to netmask
    bitmask = 0xffffffff ^ (1 << 32 - local_cidr) - 1
    local_netmask = inet_ntop(AF_INET, pack('!I', bitmask))

    # Set ntp-servers
    ntp_servers = ", ".join(lib.get_servers_for_node('ntpd', host))
    if not ntp_servers:
        ntp_servers = ('0.pool.ntp.org, '
                       '1.pool.ntp.org, '
                       '2.pool.ntp.org, '
                       '3.pool.ntp.org')

    # Set domain-name-servers
    resolver_ipv4_addresses = []
    for hostname, addresses in lib.resolve_nodes_to_ip(
            lib.get_servers_for_node('resolver', host)).iteritems():

        resolver_ipv4_addresses.append(addresses[0])

    resolver_ipv4_addresses.sort()
    domain_name_servers = ", ".join(resolver_ipv4_addresses)

    if not domain_name_servers:
        domain_name_servers = '8.8.8.8, 8.8.4.4'

    # Set tftp-server-name
    tftp_server_name_address = lib.resolve_nodes_to_ip(
        ['pxe.event.dreamhack.se'])
    tftp_server_name = tftp_server_name_address['pxe.event.dreamhack.se'][0]

    # Set next-server
    next_server_addresses = lib.resolve_nodes_to_ip(['pxe.event.dreamhack.se'])
    next_server = next_server_addresses['pxe.event.dreamhack.se'][0]

    # Get current event, used to decide name of dhcpinfo database
    current_event = lib.get_current_event()

    info = {}
    info['active'] = active
    info['active_node'] = active_node
    info['scopes'] = scopes
    info['ntp_servers'] = ntp_servers
    info['domain_name_servers'] = domain_name_servers
    info['tftp_server_name'] = tftp_server_name
    info['next_server'] = next_server
    info['local_subnet'] = local_subnet
    info['local_netmask'] = local_netmask
    info['current_event'] = current_event

    return {'dhcpd': info}
Exemplo n.º 10
0
def generate_backend(host, local_services):
    scrape_configs = []
    scrape_configs.extend(local_services)
    domain = lib.get_domain(host)

    basic_auth = lib.read_secret('services/monitoring:login')

    # Find services that wants to be monitored
    manifest = yaml.load(file(MANIFEST_PATH).read())
    for package, spec in manifest['packages'].iteritems():
        if spec is None or 'monitor' not in spec:
            continue

        urls = (spec['monitor']['url']
                if isinstance(spec['monitor']['url'], dict) else {
                    None: spec['monitor']['url']
                })
        for url_id, url_str in urls.iteritems():
            url = urlparse.urlparse(url_str)
            targets = []
            for target in sorted(
                    lib.get_nodes_with_package(package, domain).keys()):
                targets.append(target if url.port is None else '%s:%d' %
                               (target, url.port))
            scrape_config = {
                'job_name': package + ('-%s' % url_id if url_id else ''),
                'metrics_path': url.path,
                'scheme': url.scheme,
                'static_configs': [{
                    'targets': sorted(targets)
                }],
            }
            if 'interval' in spec['monitor']:
                scrape_config['scrape_interval'] = spec['monitor']['interval']
            if 'labels' in spec['monitor']:
                scrape_config['static_configs'][0]['labels'] = spec['monitor'][
                    'labels']
            # Only allow authentication over https
            if spec['monitor'].get('auth', False) and url.scheme == 'https':
                scrape_config['basic_auth'] = basic_auth
            scrape_configs.append(scrape_config)

    # Layer specific monitoring
    layers = lib.get_layers(domain)

    snmp_nodes = {}
    ssh_nodes = {}
    for layer in layers:
        hosts = lib.get_nodes_with_layer(layer, domain)
        snmp_mute = lib.get_nodes_with_layer(layer, domain, 'no-snmp')
        ssh_mute = lib.get_nodes_with_layer(layer, domain, 'no-ssh')
        snmp_nodes[layer] = list(set(hosts) - set(snmp_mute))
        ssh_nodes[layer] = [x + ':22' for x in set(hosts) - set(ssh_mute)]

    # SNMP
    for layer in layers:
        # TODO(bluecmd): Use options for this
        if layer == 'access':
            host = 'snmp2.event.dreamhack.se'
        else:
            host = 'snmp1.event.dreamhack.se'
        snmp = blackbox('snmp_%s' % layer,
                        host,
                        snmp_nodes[layer], {'layer': [layer]},
                        labels={'layer': layer})
        snmp['scrape_interval'] = '30s'
        snmp['scrape_timeout'] = '30s'
        scrape_configs.append(snmp)

    # SSH
    for layer in layers:
        for host in ['jumpgate1', 'jumpgate2', 'rancid']:
            fqdn = host + '.event.dreamhack.se:9115'
            ssh = blackbox('ssh_%s_%s' % (layer, host),
                           fqdn,
                           ssh_nodes[layer], {'module': ['ssh_banner']},
                           labels={'layer': layer})
            ssh['scrape_interval'] = '30s'
            ssh['scrape_timeout'] = '30s'
            scrape_configs.append(ssh)

    # Add external service-discovery
    external = {
        'job_name': 'external',
        'file_sd_configs': [{
            'files': ['/etc/prometheus/external/*.yaml'],
        }],
    }
    scrape_configs.append(external)

    if host.endswith('event.dreamhack.se'):
        # Event should scrape puppet.tech.dreamhack.se to get information about
        # puppet runs
        puppet = {
            'job_name': 'puppet_runs',
            'metrics_path': '/metrics',
            'scrape_interval': '60s',
            'scrape_timeout': '55s',
            'static_configs': [{
                'targets': ['puppet.tech.dreamhack.se:9100'],
            }],
        }
        scrape_configs.append(puppet)

    vcenter = {
        'job_name': 'vmware_vcenter',
        'metrics_path': '/metrics',
        'scrape_interval': '60s',
        'scrape_timeout': '55s',
        'static_configs': [{
            'targets': ['provision.event.dreamhack.se:9272'],
        }],
    }
    scrape_configs.append(vcenter)

    # Make sure that all metrics have a host label.
    # This rule uses the existing host label if there is one,
    # stripping of the port (which shouldn't be part of the host label anyway)
    # *or* if that label does not exist it uses the instance label
    # (again stripping of the port)
    relabel = {
        'regex': r':?([^:]*):?.*',
        'separator': ':',
        'replacement': '${1}',
        'source_labels': ['host', 'instance'],
        'target_label': 'host',
    }

    mrc = 'metric_relabel_configs'
    for scrape in scrape_configs:
        if mrc in scrape:
            scrape[mrc].append(relabel)
        else:
            scrape[mrc] = [relabel]
    return {'scrape_configs': scrape_configs}