Esempio n. 1
0
def request_server_certificates():
    '''Send the data that is required to create a server certificate for
    this server.'''
    website = endpoint_from_flag('website.available')
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()
    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        get_ingress_address(website.endpoint_name),
        socket.gethostname(),
    ]
    hacluster = endpoint_from_flag('ha.connected')
    if hacluster:
        vips = hookenv.config('ha-cluster-vip').split()
        dns_record = hookenv.config('ha-cluster-dns')
        if vips:
            sans.extend(vips)
        else:
            sans.append(dns_record)

    # maybe they have extra names they want as SANs
    extra_sans = hookenv.config('extra_sans')
    if extra_sans and not extra_sans == "":
        sans.extend(extra_sans.split())
    # Request a server cert with this information.
    tls_client.request_server_cert(common_name,
                                   sans,
                                   crt_path=server_crt_path,
                                   key_path=server_key_path)
Esempio n. 2
0
def start_che():
    # This container isn't Che. This container starts Che. This should be run
    # in interactive mode, but this container waits until it can reach che on
    # its public_ip. On a public cloud, public_ip might only be accessible
    # after running `juju expose`, so this might never exit. Because of this
    # reason, we run the container in daemon mode, check che's status ourselves
    # and kill the container manually after Che is up.
    print('Starting Che...')
    container_id = check_output([
        'docker', 'run', '-id', '-v',
        '/var/run/docker.sock:/var/run/docker.sock', '-v',
        '/home/ubuntu/:/data', '-e', 'CHE_HOST={}'.format(unit_public_ip()),
        '-e', 'CHE_DOCKER_IP_EXTERNAL={}'.format(unit_public_ip()),
        'eclipse/che:{}'.format(CHE_VERSION), 'start', '--fast'
    ],
                                universal_newlines=True).rstrip()
    wait_until_che_running()
    print('Che Started!')
    print('Stopping Startup Container...')
    try:
        sys.stdout.flush()
        check_call(['docker', 'stop', container_id])
    except CalledProcessError:
        # container has already stopped
        print("Killing startup container failed.")
    print("Removing startup container...")
    sys.stdout.flush()
    check_call(['docker', 'rm', container_id])
    print("Startup container removed!")
Esempio n. 3
0
def start_che():
    # This container isn't Che. This container starts Che. This should be run
    # in interactive mode, but this container waits until it can reach che on
    # its public_ip. On a public cloud, public_ip might only be accessible
    # after running `juju expose`, so this might never exit. Because of this
    # reason, we run the container in daemon mode, check che's status ourselves
    # and kill the container manually after Che is up.
    print('Starting Che...')
    container_id = check_output([
        'docker', 'run',
        '-id',
        '-v', '/var/run/docker.sock:/var/run/docker.sock',
        '-v', '/home/ubuntu/:/data',
        '-e', 'CHE_HOST={}'.format(unit_public_ip()),
        '-e', 'CHE_DOCKER_IP_EXTERNAL={}'.format(unit_public_ip()),
        'eclipse/che:{}'.format(config()['version']),
        'start',
        '--fast'], universal_newlines=True).rstrip()
    wait_until_che_running()
    print('Che Started!')
    print('Stopping Startup Container...')
    try:
        sys.stdout.flush()
        check_call(['docker', 'stop', container_id])
    except CalledProcessError:
        # container has already stopped
        print("Killing startup container failed.")
    print("Removing startup container...")
    sys.stdout.flush()
    check_call(['docker', 'rm', container_id])
    print("Startup container removed!")
def send_data(tls):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()

    # Get the SDN gateway based on the cidr address.
    kubernetes_service_ip = get_kubernetes_service_ip()

    domain = hookenv.config('dns_domain')
    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        hookenv.unit_private_ip(),
        socket.gethostname(),
        kubernetes_service_ip,
        'kubernetes',
        'kubernetes.{0}'.format(domain),
        'kubernetes.default',
        'kubernetes.default.svc',
        'kubernetes.default.svc.{0}'.format(domain)
    ]

    # maybe they have extra names they want as SANs
    extra_sans = hookenv.config('extra_sans')
    if extra_sans and not extra_sans == "":
        sans.extend(extra_sans.split())

    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')
    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
def send_data(tls, kube_api_endpoint):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()

    # Get the SDN gateway based on the cidr address.
    kubernetes_service_ip = get_kubernetes_service_ip()

    # Get ingress address
    ingress_ip = get_ingress_address(kube_api_endpoint.relation_name)

    domain = hookenv.config('dns_domain')
    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(), ingress_ip,
        socket.gethostname(), kubernetes_service_ip, 'kubernetes',
        'kubernetes.{0}'.format(domain), 'kubernetes.default',
        'kubernetes.default.svc', 'kubernetes.default.svc.{0}'.format(domain)
    ]

    # maybe they have extra names they want as SANs
    extra_sans = hookenv.config('extra_sans')
    if extra_sans and not extra_sans == "":
        sans.extend(extra_sans.split())

    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')
    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 6
0
def send_data(tls):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()

    # Get the SDN gateway based on the cidr address.
    kubernetes_service_ip = get_kubernetes_service_ip()

    domain = hookenv.config('dns_domain')
    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        hookenv.unit_private_ip(),
        socket.gethostname(),
        kubernetes_service_ip,
        'kubernetes',
        'kubernetes.{0}'.format(domain),
        'kubernetes.default',
        'kubernetes.default.svc',
        'kubernetes.default.svc.{0}'.format(domain)
    ]
    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')
    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
def send_data():
    '''Send the data that is required to create a server certificate for
    this server.'''
    kube_control = endpoint_from_flag('kube-control.connected')

    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()

    ingress_ip = get_ingress_address(kube_control.endpoint_name)

    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        ingress_ip,
        gethostname()
    ]

    # Request a server cert with this information.
    layer.tls_client.request_server_cert(common_name, sorted(set(sans)),
                                         crt_path=server_crt_path,
                                         key_path=server_key_path)

    # Request a client cert for kubelet.
    layer.tls_client.request_client_cert('system:kubelet',
                                         crt_path=client_crt_path,
                                         key_path=client_key_path)
Esempio n. 8
0
def prepare_tls_certificates(tls):
    status_set('maintenance', 'Requesting tls certificates.')
    common_name = hookenv.unit_public_ip()
    sans = []
    sans.append(hookenv.unit_public_ip())
    sans.append(hookenv.unit_private_ip())
    sans.append(socket.gethostname())
    certificate_name = hookenv.local_unit().replace('/', '_')
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 9
0
def send_data():
    # Send the data that is required to create a server certificate for
    # this server.
    config = hookenv.config()
    server_crt_path = crtPath('server')
    client_crt_path = crtPath('client')
    server_key_path = keyPath('server')
    client_key_path = keyPath('client')
    ca_crt_path = caPath()
    # Use the private ip of this unit as the Common Name for the certificate.
    if config['ssl_cert']:
        for certs_path in ('server_crt_path', 'client_crt_path'):
            with open(certs_path, "wb") as fs:
                os.chmod(
                    certs_path,
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
                fs.write(base64.b64decode(config['ssl_cert']))
            if config['ssl_key']:
                with open(certs_path, "wb") as fks:
                    os.chmod(certs_path, stat.S_IWUSR | stat.S_IWUSR)
                    fks.write(base64.b64decode(config['ssl_key']))
        import_srv_crt_to_keystore()
        if config['ssl_ca']:
            with open(ca_crt_path, "wb") as fca:
                os.chmod(
                    ca_crt_path,
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
                fca.write(base64.b64decode(config['ssl_ca']))
        import_ca_crt_to_keystore()
    else:
        common_name = hookenv.unit_private_ip()
        common_public_name = hookenv.unit_public_ip()
        sans = [
            common_name,
            common_public_name,
            hookenv.unit_public_ip(),
            socket.gethostname(),
            socket.getfqdn(),
        ]

        # maybe they have extra names they want as SANs
        extra_sans = hookenv.config('subject_alt_names')
        if extra_sans and not extra_sans == "":
            sans.extend(extra_sans.split())

        # Request a server cert with this information.
        tls_client.request_server_cert(common_name,
                                       sans,
                                       crt_path=server_crt_path,
                                       key_path=server_key_path)

        # Request a client cert with this information.
        tls_client.request_client_cert(common_name,
                                       sans,
                                       crt_path=client_crt_path,
                                       key_path=client_key_path)
Esempio n. 10
0
def prepare_tls_certificates(tls):
    common_name = hookenv.unit_public_ip()
    sans = set()
    sans.add(hookenv.unit_public_ip())
    sans.update(get_ingress_addresses('db'))
    sans.update(get_ingress_addresses('cluster'))
    sans.add(socket.gethostname())
    sans = sorted(sans)
    certificate_name = hookenv.local_unit().replace('/', '_')
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 11
0
def stop_che():
    print('Stopping Che...')
    sys.stdout.flush()
    check_call([
        'docker', 'run', '-i', '--rm', '-v',
        '/var/run/docker.sock:/var/run/docker.sock', '-v',
        '/home/ubuntu/:/data', '-e', 'CHE_HOST={}'.format(unit_public_ip()),
        '-e', 'CHE_DOCKER_IP_EXTERNAL={}'.format(unit_public_ip()),
        'eclipse/che:{}'.format(CHE_VERSION), 'stop'
    ])
    print('Che is stopped!')
Esempio n. 12
0
def prepare_tls_certificates(tls):
    status_set('maintenance', 'Requesting tls certificates.')
    common_name = hookenv.unit_public_ip()
    sans = set()
    sans.add(hookenv.unit_public_ip())
    sans.add(get_ingress_address('db'))
    sans.add(get_ingress_address('cluster'))
    sans.add(socket.gethostname())
    sans = list(sans)
    certificate_name = hookenv.local_unit().replace('/', '_')
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 13
0
def send_data(tls):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()

    # Create SANs that the tls layer will add to the server cert.
    sans = [hookenv.unit_public_ip(), hookenv.unit_private_ip(), gethostname()]

    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')

    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 14
0
 def send_data(tls):
     '''Send the data that is required to create a server certificate for
     this server.'''
     # Use the public ip of this unit as the Common Name for the certificate.
     common_name = hookenv.unit_public_ip()
     # Get a list of Subject Alt Names for the certificate.
     sans = []
     sans.append(hookenv.unit_public_ip())
     sans.append(hookenv.unit_private_ip())
     sans.append(socket.gethostname())
     layer.tls_client.request_server_cert(common_name,
                                          sans,
                                          crt_path='/etc/certs/server.crt',
                                          key_path='/etc/certs/server.key')
Esempio n. 15
0
def stop_che():
    print('Stopping Che...')
    sys.stdout.flush()
    check_call([
        'docker', 'run',
        '-i',
        '--rm',
        '-v', '/var/run/docker.sock:/var/run/docker.sock',
        '-v', '/home/ubuntu/:/data',
        '-e', 'CHE_HOST={}'.format(unit_public_ip()),
        '-e', 'CHE_DOCKER_IP_EXTERNAL={}'.format(unit_public_ip()),
        'eclipse/che:{}'.format(config()['version']),
        'stop'])
    print('Che is stopped!')
Esempio n. 16
0
def request_server_certificates(tls):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()
    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        hookenv.unit_private_ip(),
        socket.gethostname(),
    ]
    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')
    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
def configure():
    zookeeper = relations.endpoint_from_flag('endpoint.zookeeper.available')
    connections = []
    try:
        connections_yaml = hookenv.config().get('connections')
        if connections_yaml:
            connections = yaml.safe_load(connections_yaml)
    except yaml.YAMLError:
        pass
    mysql = relations.endpoint_from_flag('shared-db.available')
    conf = {
        'zk_servers': [],
        'connections': connections,
        'database': mysql,
        'git_username': hookenv.config().get('git_username'),
        'git_email': hookenv.config().get('git_email'),
        'executor_disk_limit': hookenv.config().get('executor_disk_limit',
                                                    '-1'),
        'public_ip': hookenv.unit_public_ip(),
    }
    if hookenv.config()['tenant-config']:
        conf['tenant_config_script'] = True
    for zk_unit in zookeeper.list_unit_data():
        conf['zk_servers'].append("{}:{}".format(
            zk_unit['host'].replace('"', ''), zk_unit['port']))
    templating.render('zuul.conf',
                      '/etc/zuul/zuul.conf',
                      context=conf,
                      perms=0o650,
                      group='zuul',
                      owner='zuul')
    if reactive.helpers.any_file_changed(['/etc/zuul/zuul.conf']):
        reactive.set_flag('service.zuul.restart')
        reactive.set_flag('zuul.reload_config')
        reactive.set_flag('zuul.configured')
Esempio n. 18
0
def setup_mattermost_backend(postgres_relation):
    print("Configuring and starting backend service.")
    _configure_mattermost_postgres(postgres_relation.master.uri)
    service_restart('mattermost')
    # Set build number for Juju status
    try:
        output = check_output(
            ['/opt/mattermost/bin/platform', 'version'],
            cwd='/opt/mattermost/bin/',
            universal_newlines=True,
            stderr=STDOUT,
        )
    except CalledProcessError as e:
        print(e.output)
        raise
    build_number = re.search(r'Build Number: ([0-9]+.[0-9]+.[0-9])+\n',
                             output).group(1)
    application_version_set(build_number)
    open_port(8065)
    # The next two aren't really open. This is a fix for the following issue:
    #    no expose possible before `open-port`.
    #    no `open-port` of 80 and 443 before ssl.
    #    no ssl certificate before `expose`.
    open_port(config().get('port'))
    open_port(443)
    status_set(
        'active', 'Ready (http://{}:8065 [Insecure! Please set fqdn!])'.format(
            unit_public_ip()))
    set_state('mattermost.backend.started')
Esempio n. 19
0
def config_file_changed():
    """
    When /etc/jupyterhub/jupyterhub_config.py changes, restart jupyterhub.
    """
    subprocess.check_call(['systemctl', 'restart', 'jupyterhub'])
    hookenv.status_set('active', 'Ready: http://{public_ip}:{port}'.format(
        public_ip=hookenv.unit_public_ip(), port=hookenv.config('port')))
Esempio n. 20
0
def change_config():
    conf = config()
    if conf.changed('port') or conf.changed('authentication'):
        old_port = conf.previous('port')
        render(source='arangod.conf',
               target='/etc/arangodb3/arangod.conf',
               context={
                   'port': str(conf['port']),
                   'authentication': str(conf['authentication']).lower()
               })
        if old_port is not None:
            close_port(old_port)
        open_port(conf['port'])
    if conf['root_password'] != kv.get(
            'password') and conf['root_password'] != "":
        password = conf['root_password']
        old_password = kv.get('password')
        kv.set('password', password)
        TCP = 'tcp://' + unit_public_ip() + ':' + str(conf['port'])
        require = "require('@arangodb/users').update('root', '{}', true)".format(
            password)
        subprocess.check_call([
            'arangosh', '--server.endpoint', TCP, '--server.username', 'root',
            '--server.password', old_password, '--javascript.execute-string',
            require
        ])
Esempio n. 21
0
def config_with_reverseproxy(reverseproxy):
    services = reverseproxy.services()
    cfg = hookenv.config()

    for service in services:
        service_dir = '/var/lib/tor/%s' % (service['service_name'])
        if not os.path.isdir(service_dir):
            check_call(['install', '-d', service_dir, '-o', 'debian-tor', '-m', '700'])

    bridges = []
    for bridge in cfg.get('bridges', '').split(','):
        fields = bridge.split()
        if len(fields) > 1:
            addr, fp = fields[:2]
            bridges.append({'addr': addr, 'fingerprint': fp})

    render(source='torrc',
        target='/etc/tor/torrc',
        owner='root',
        perms=0o644,
        context={
            'cfg': cfg,
            'services': services,
            'bridges': bridges,
            'public_address': hookenv.unit_public_ip(),
            'private_address': hookenv.unit_private_ip(),
        })
    remove_state('reverseproxy.available')
    set_state('tor.start')
Esempio n. 22
0
def create_certificate_authority(certificate_authority=None):
    '''Return the CA and server certificates for this system. If the CA is
    empty, generate a self signged certificate authority.'''
    # followers are not special, do not generate a ca
    if not is_leader():
        return
    # Create an absolute path so current directory does not affect the result.
    easyrsa3_dir = os.path.join(hookenv.charm_dir(), 'easy-rsa/easyrsa3')
    with chdir(easyrsa3_dir):
        ca_file = 'pki/ca.crt'
        # Check if an old CA exists.
        if os.path.isfile(ca_file):
            # Initialize easy-rsa (by deleting old pki) so a CA can be created.
            init = './easyrsa --batch init-pki 2>&1'
            check_call(split(init))
        # When the CA is not None write the CA file.
        if certificate_authority:
            # Write the certificate authority from configuration.
            with open(ca_file, 'w') as fp:
                fp.write(certificate_authority)
        else:
            # The Certificate Authority does not exist build a self signed one.
            # The Common Name (CN) for a certificate must be an IP or hostname.
            cn = hookenv.unit_public_ip()
            # Create a self signed CA with the CN, stored pki/ca.crt
            build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1'
            check_call(split(build_ca.format(cn)))
            # Read the CA so we can return the contents from this method.
            with open(ca_file, 'r') as fp:
                certificate_authority = fp.read()
    set_state('certificate authority available')
    return certificate_authority
Esempio n. 23
0
def get_sans(address_list=None):
    '''Return a string suitable for the easy-rsa subjectAltNames. This method
    will add a valid SANs string with the public IP, private IP, and hostname
    of THIS system.'''
    # The unit_public_ip could be a FQDN or IP address depending on provider.
    public = hookenv.unit_public_ip()

    # unitdata returns None if not found. Handle the occurrence of no
    # addresses passed, and initialize to an empty array
    if not address_list:
        address_list = []

    if public not in address_list:
        address_list.append(public)
    # The unit_private_ip could be a FQDN or IP address depending on provider.
    private = hookenv.unit_private_ip()
    if private not in address_list:
        address_list.append(private)
    # The hostname is usually a string, not an IP address.
    hostname = socket.gethostname()
    if hostname not in address_list:
        address_list.append(hostname)

    sans = []
    for address in address_list:
        if _is_ip(address):
            sans.append('IP:{0}'.format(address))
        else:
            sans.append('DNS:{0}'.format(address))
    return ','.join(sans)
Esempio n. 24
0
def get_sans(address_list=None):
    """Return a string suitable for the easy-rsa subjectAltNames. This method
    will add a valid SANs string with the public IP, private IP, and hostname
    of THIS system."""
    # The unit_public_ip could be a FQDN or IP address depending on provider.
    public = hookenv.unit_public_ip()

    # unitdata returns None if not found. Handle the occurrence of no
    # addresses passed, and initialize to an empty array
    if not address_list:
        address_list = []

    if public not in address_list:
        address_list.append(public)
    # The unit_private_ip could be a FQDN or IP address depending on provider.
    private = hookenv.unit_private_ip()
    if private not in address_list:
        address_list.append(private)
    # The hostname is usually a string, not an IP address.
    hostname = socket.gethostname()
    if hostname not in address_list:
        address_list.append(hostname)

    sans = []
    for address in address_list:
        if _is_ip(address):
            sans.append("IP:{0}".format(address))
        else:
            sans.append("DNS:{0}".format(address))
    return ",".join(sans)
Esempio n. 25
0
def create_server_certificate(name="server"):
    """Create the server certificate and server key."""
    # Use the public ip as the Common Name for the server certificate.
    cn = hookenv.unit_public_ip()
    # Create an absolute path so current directory does not affect the result.
    easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3")
    with chdir(easyrsa3_dir):
        server_file = "pki/issued/{0}.crt".format(name)
        # Get a list of extra sans from the unitdata kv module.
        extra_sans = unitdata.kv().get("extra_sans")
        # Get a string compatible with easyrsa for the subject-alt-names.
        sans = get_sans(extra_sans)
        # Do not regenerate the server certificate if it already exists.
        if not os.path.isfile(server_file):
            # Create a server certificate for the server based on the CN.
            server = (
                "./easyrsa --batch --req-cn={0} --subject-alt-name={1} "
                "build-server-full {2} nopass 2>&1".format(cn, sans, name)
            )
            check_call(split(server))
            # Read the server certificate from the filesystem.
            with open(server_file, "r") as fp:
                server_cert = fp.read()
            # The key name is also used to set the reactive state.
            set_cert("tls.server.certificate", server_cert)
Esempio n. 26
0
def create_certificate_authority(certificate_authority=None):
    """Return the CA and server certificates for this system. If the CA is
    empty, generate a self signged certificate authority."""
    # followers are not special, do not generate a ca
    if not is_leader():
        return
    # Create an absolute path so current directory does not affect the result.
    easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3")
    with chdir(easyrsa3_dir):
        ca_file = "pki/ca.crt"
        # Check if an old CA exists.
        if os.path.isfile(ca_file):
            # Initialize easy-rsa (by deleting old pki) so a CA can be created.
            init = "./easyrsa --batch init-pki 2>&1"
            check_call(split(init))
        # When the CA is not None write the CA file.
        if certificate_authority:
            # Write the certificate authority from configuration.
            with open(ca_file, "w") as fp:
                fp.write(certificate_authority)
        else:
            # The Certificate Authority does not exist build a self signed one.
            # The Common Name (CN) for a certificate must be an IP or hostname.
            cn = hookenv.unit_public_ip()
            # Create a self signed CA with the CN, stored pki/ca.crt
            build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1'
            check_call(split(build_ca.format(cn)))
            # Read the CA so we can return the contents from this method.
            with open(ca_file, "r") as fp:
                certificate_authority = fp.read()
    set_state("certificate authority available")
    return certificate_authority
Esempio n. 27
0
def create_csr(tls):
    """Create a certificate signing request (CSR). Only the followers need to
    run this operation."""
    if not is_leader():
        # Create an absolute path to easyrsa3 to change to that directory.
        easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3")
        # Use an absolute path for this context manager.
        with chdir(easyrsa3_dir):
            # Must remove the path characters from the unit name.
            path_name = hookenv.local_unit().replace("/", "_")
            # The reqest will be named with unit_name.req
            req_file = "pki/reqs/{0}.req".format(path_name)
            # If the request already exists do not generate another one.
            if os.path.isfile(req_file):
                remove_state("create certificate signing request")
                return

            # The Common Name is the public address of the system.
            cn = hookenv.unit_public_ip()
            hookenv.log("Creating the CSR for {0}".format(path_name))
            sans = get_sans()
            # Create a CSR for this system with the subject and SANs.
            gen_req = "./easyrsa --batch --req-cn={0} --subject-alt-name={1}" " gen-req {2} nopass 2>&1".format(
                cn, sans, path_name
            )
            check_call(split(gen_req))
            # Read the CSR file.
            with open(req_file, "r") as fp:
                csr = fp.read()
            # Set the CSR on the relation object.
            tls.set_csr(csr)
    else:
        hookenv.log("The leader does not need to create a CSR.")
Esempio n. 28
0
def get_template_data():
    rels = hookenv.relations()
    config = hookenv.config()
    version = config['version']
    template_data = {}
    template_data['etcd_servers'] = ','.join([
        'http://%s:%s' % (s[0], s[1]) for s in sorted(
            get_rel_hosts('etcd', rels, ('hostname', 'port')))])
    template_data['minions'] = ','.join(get_rel_hosts('minions-api', rels))
    private_ip = hookenv.unit_private_ip()
    public_ip = hookenv.unit_public_ip()
    template_data['api_public_address'] = _bind_addr(public_ip)
    template_data['api_private_address'] = _bind_addr(private_ip)
    template_data['bind_address'] = '127.0.0.1'
    template_data['api_http_uri'] = 'http://%s:%s' % (private_ip, 8080)
    template_data['api_https_uri'] = 'https://%s:%s' % (private_ip, 6443)

    arch = subprocess.check_output(['dpkg', '--print-architecture']).strip()

    template_data['web_uri'] = '/kubernetes/%s/local/bin/linux/%s/' % (version,
                                                                       arch)
    if version == 'local':
        template_data['alias'] = hookenv.charm_dir() + '/files/output/'
    else:
        directory = '/opt/kubernetes/_output/local/bin/linux/%s/' % arch
        template_data['alias'] = directory
    _encode(template_data)
    return template_data
Esempio n. 29
0
def master_kubeconfig():
    '''Create the kubernetes configuration for the master unit. The master
    should create a package with the client credentials so the user can
    interact securely with the apiserver.'''
    hookenv.log('Creating Kubernetes configuration for master node.')
    directory = '/srv/kubernetes'
    ca = '/srv/kubernetes/ca.crt'
    key = '/srv/kubernetes/client.key'
    cert = '/srv/kubernetes/client.crt'
    # Get the public address of the apiserver so users can access the master.
    server = 'https://{0}:{1}'.format(hookenv.unit_public_ip(), '6443')
    # Create the client kubeconfig so users can access the master node.
    create_kubeconfig(directory, server, ca, key, cert)
    # Copy the kubectl binary to this directory.
    cmd = 'cp -v /usr/local/bin/kubectl {0}'.format(directory)
    check_call(split(cmd))
    # Use a context manager to run the tar command in a specific directory.
    with chdir(directory):
        # Create a package with kubectl and the files to use it externally.
        cmd = 'tar -cvzf /home/ubuntu/kubectl_package.tar.gz ca.crt ' \
              'client.key client.crt kubectl kubeconfig'
        check_call(split(cmd))

    # This sets up the client workspace consistently on the leader and nodes.
    node_kubeconfig()
    set_state('kubeconfig.created')
Esempio n. 30
0
def render_systemd_conf():
    """Render fiche systemd conf
    """

    if config('fqdn'):
        server_name = config('fqdn')
    else:
        server_name = unit_public_ip()

    # Systemd vars
    SYSTEMD_CTXT = {
        'fiche_server_address': server_name,
        'fiche_server_port': config('fiche-server-port'),
        'slug_size': config('slug-size'),
        'buffer_size': config('buffer-size')
    }

    if os.path.exists('/etc/systemd/system/fiche.service'):
        os.remove('/etc/systemd/system/fiche.service')

    # Render systemd template
    render(source="fiche.service.tmpl",
           target="/etc/systemd/system/fiche.service",
           perms=0o644,
           owner="root",
           context=SYSTEMD_CTXT)

    # Open fiche server port
    open_port(config('fiche-server-port'))

    # Set 'fiche.systemd.configured'
    set_state('fiche.systemd.configured')
Esempio n. 31
0
def config_leader():
    leader_set(hostname=hookenv.unit_private_ip())
    leader_set(public_ip=hookenv.unit_public_ip())
    leader_set(username='******')
    leader_set(password=hookenv.config('carte_password'))
    leader_set(port=hookenv.config('carte_port'))
    render_master_config()
Esempio n. 32
0
def setup():
    unit_data = kv()
    if not unit_data.get('gogs.db'):
        hookenv.status_set('blocked', 'need relation to postgresql')
        return

    secret_key = unit_data.get('gogs.secret_key')
    if not secret_key:
        secret_key = base64.b64encode(os.urandom(32)).decode('utf-8')
        unit_data.set('gogs.secret_key', secret_key)

    conf = hookenv.config()
    if not conf.get('host'):
        conf['host'] = hookenv.unit_public_ip()

    root = unit_data.get('gogs.root', '')
    if root and not root.endswith('/'):
        root = root + '/'

    install_context = get_install_context()

    render(source='app.ini',
           target="/opt/gogs/custom/conf/app.ini",
           perms=0o644,
           context={
               'conf': conf,
               'db': unit_data.get('gogs.db'),
               'secret_key': secret_key,
               'root': root,
               'home': install_context['home'],
               'user': install_context['user'],
           })
    restart_service()
    hookenv.status_set('active', 'ready')
Esempio n. 33
0
def create_csr(tls):
    '''Create a certificate signing request (CSR). Only the followers need to
    run this operation.'''
    if not is_leader():
        # Create an absolute path to easyrsa3 to change to that directory.
        easyrsa3_dir = os.path.join(hookenv.charm_dir(), 'easy-rsa/easyrsa3')
        # Use an absolute path for this context manager.
        with chdir(easyrsa3_dir):
            # Must remove the path characters from the unit name.
            path_name = hookenv.local_unit().replace('/', '_')
            # The reqest will be named with unit_name.req
            req_file = 'pki/reqs/{0}.req'.format(path_name)
            # If the request already exists do not generate another one.
            if os.path.isfile(req_file):
                remove_state('create certificate signing request')
                return

            # The Common Name is the public address of the system.
            cn = hookenv.unit_public_ip()
            hookenv.log('Creating the CSR for {0}'.format(path_name))
            sans = get_sans()
            # Create a CSR for this system with the subject and SANs.
            gen_req = './easyrsa --batch --req-cn={0} --subject-alt-name={1}' \
                      ' gen-req {2} nopass 2>&1'.format(cn, sans, path_name)
            check_call(split(gen_req))
            # Read the CSR file.
            with open(req_file, 'r') as fp:
                csr = fp.read()
            # Set the CSR on the relation object.
            tls.set_csr(csr)
    else:
        hookenv.log('The leader does not need to create a CSR.')
Esempio n. 34
0
def config_with_reverseproxy(reverseproxy):
    services = reverseproxy.services()
    cfg = hookenv.config()

    for service in services:
        service_dir = '/var/lib/tor/{}'.format(service['service_name'])
        if not os.path.isdir(service_dir):
            check_call([
                'install', '-d', service_dir, '-o', 'debian-tor', '-m', '700'
            ])

    bridges = []
    for bridge in cfg.get('bridges', '').split(','):
        fields = bridge.split()
        if len(fields) > 1:
            addr, fp = fields[:2]
            bridges.append({'addr': addr, 'fingerprint': fp})

    render(source='torrc',
           target='/etc/tor/torrc',
           owner='root',
           perms=0o644,
           context={
               'cfg': cfg,
               'services': services,
               'bridges': bridges,
               'public_address': hookenv.unit_public_ip(),
               'private_address': hookenv.unit_private_ip(),
           })
    remove_state('reverseproxy.available')
    set_state('tor.start')
Esempio n. 35
0
def create_certificate_authority():
    '''Return the CA and server certificates for this system. If the CA is
    empty, generate a self signged certificate authority.'''
    with chdir(easyrsa_directory):
        # The Common Name (CN) for a certificate must be an IP or hostname.
        cn = hookenv.unit_public_ip()
        # Create a self signed CA with the CN, stored pki/ca.crt
        build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1'
        # Build a self signed Certificate Authority.
        check_call(split(build_ca.format(cn)))

        ca_file = 'pki/ca.crt'
        # Read the CA so it can be returned in leader data.
        with open(ca_file, 'r') as stream:
            certificate_authority = stream.read()

        key_file = 'pki/private/ca.key'
        # Read the private key so it can be set in leader data.
        with open(key_file, 'r') as stream:
            ca_key = stream.read()

        # Set these values on the leadership data.
        leader_set({'certificate_authority': certificate_authority})
        leader_set({'certificate_authority_key': ca_key})
        # Install the CA on this system as a trusted CA.
        install_ca(certificate_authority)
        # Create a client certificate for this CA.
        client_cert, client_key = create_client_certificate()
        # Set the client certificate and key on leadership data.
        leader_set({'client_certificate': client_cert})
        leader_set({'client_key': client_key})
        status_set('active', 'Certificiate Authority available')
    set_state('easyrsa.certificate.authority.available')
Esempio n. 36
0
def create_certificate_authority():
    '''Return the CA and server certificates for this system. If the CA is
    empty, generate a self signged certificate authority.'''
    with chdir(easyrsa_directory):
        # The Common Name (CN) for a certificate must be an IP or hostname.
        cn = hookenv.unit_public_ip()
        # Create a self signed CA with the CN, stored pki/ca.crt
        build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1'
        # Build a self signed Certificate Authority.
        check_call(split(build_ca.format(cn)))

        ca_file = 'pki/ca.crt'
        # Read the CA so it can be returned in leader data.
        with open(ca_file, 'r') as stream:
            certificate_authority = stream.read()

        key_file = 'pki/private/ca.key'
        # Read the private key so it can be set in leader data.
        with open(key_file, 'r') as stream:
            ca_key = stream.read()

        # Set these values on the leadership data.
        leader_set({'certificate_authority': certificate_authority})
        leader_set({'certificate_authority_key': ca_key})
        # Install the CA on this system as a trusted CA.
        install_ca(certificate_authority)
        # Create a client certificate for this CA.
        client_cert, client_key = create_client_certificate()
        # Set the client certificate and key on leadership data.
        leader_set({'client_certificate': client_cert})
        leader_set({'client_key': client_key})
        status_set('active', 'Certificiate Authority available')
    set_state('easyrsa.certificate.authority.available')
Esempio n. 37
0
def master_kubeconfig():
    '''Create the kubernetes configuration for the master unit. The master
    should create a package with the client credentials so the user can
    interact securely with the apiserver.'''
    hookenv.log('Creating Kubernetes configuration for master node.')
    directory = '/srv/kubernetes'
    ca = '/srv/kubernetes/ca.crt'
    key = '/srv/kubernetes/client.key'
    cert = '/srv/kubernetes/client.crt'
    # Get the public address of the apiserver so users can access the master.
    server = 'https://{0}:{1}'.format(hookenv.unit_public_ip(), '6443')
    # Create the client kubeconfig so users can access the master node.
    create_kubeconfig(directory, server, ca, key, cert)
    # Copy the kubectl binary to this directory.
    cmd = 'cp -v /usr/local/bin/kubectl {0}'.format(directory)
    check_call(split(cmd))
    # Use a context manager to run the tar command in a specific directory.
    with chdir(directory):
        # Create a package with kubectl and the files to use it externally.
        cmd = 'tar -cvzf /home/ubuntu/kubectl_package.tar.gz ca.crt ' \
              'client.key client.crt kubectl kubeconfig'
        check_call(split(cmd))

    # This sets up the client workspace consistently on the leader and nodes.
    node_kubeconfig()
    set_state('kubeconfig.created')
Esempio n. 38
0
def get_tls_sans(relation_name=None):
    '''Get all sans for our TLS certificate.

    Return all IP/DNS data that should included as alt names when we request
    a TLS cert. This includes our public/private address, local DNS name, any
    configured hostname, and the address of any related proxy.

    :return: sorted list of sans
    '''
    charm_config = hookenv.config()
    sans = [
        hookenv.unit_private_ip(),
        hookenv.unit_public_ip(),
        socket.gethostname(),
    ]
    if charm_config.get('http-host'):
        http_host = urlparse(charm_config['http-host']).hostname
        sans.append(http_host)

    if relation_name:
        proxy_sans = [hookenv.ingress_address(rid=u.rid, unit=u.unit)
                      for u in hookenv.iter_units_for_relation_name(relation_name)]
        sans.extend(proxy_sans)

    return sorted(sans)
Esempio n. 39
0
def setup():
    unit_data = kv()
    if not unit_data.get('gogs.db'):
        hookenv.status_set('blocked', 'need relation to postgresql')
        return

    secret_key = unit_data.get('gogs.secret_key')
    if not secret_key:
        secret_key = base64.b64encode(os.urandom(32)).decode('utf-8')
        unit_data.set('gogs.secret_key', secret_key)

    conf = hookenv.config()
    if not conf.get('host'):
        conf['host'] = hookenv.unit_public_ip()

    root = unit_data.get('gogs.root', '')
    if root and not root.endswith('/'):
        root = root + '/'

    render(source='app.ini',
           target="/opt/gogs/custom/conf/app.ini",
           perms=0o644,
           context={
               'conf': conf,
               'db': unit_data.get('gogs.db'),
               'secret_key': secret_key,
               'root': root,
           })
    restart_service()
    hookenv.status_set('active', 'ready')
Esempio n. 40
0
def create_certificate_authority(certificate_authority=None):
    '''Return the CA and server certificates for this system. If the CA is
    empty, generate a self signged certificate authority.'''
    # followers are not special, do not generate a ca
    if not is_leader():
        return
    with chdir('easy-rsa/easyrsa3'):
        ca_file = 'pki/ca.crt'
        # Check if an old CA exists.
        if os.path.isfile(ca_file):
            # Initialize easy-rsa (by deleting old pki) so a CA can be created.
            init = './easyrsa --batch init-pki 2>&1'
            check_call(split(init))
        # When the CA is not None write the CA file.
        if certificate_authority:
            # Write the certificate authority from configuration.
            with open(ca_file, 'w') as fp:
                fp.write(certificate_authority)
        else:
            # The Certificate Authority does not exist build a self signed one.
            # The Common Name (CN) for a certificate must be an IP or hostname.
            cn = hookenv.unit_public_ip()
            # Create a self signed CA with the CN, stored pki/ca.crt
            build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1'
            check_call(split(build_ca.format(cn)))
            # Read the CA so we can return the contents from this method.
            with open(ca_file, 'r') as fp:
                certificate_authority = fp.read()
    set_state('certificate authority available')
    return certificate_authority
Esempio n. 41
0
def get_template_data():
    rels = hookenv.relations()
    config = hookenv.config()
    version = config['version']
    template_data = {}
    template_data['etcd_servers'] = ','.join([
        'http://%s:%s' % (s[0], s[1])
        for s in sorted(get_rel_hosts('etcd', rels, ('hostname', 'port')))
    ])
    template_data['minions'] = ','.join(get_rel_hosts('minions-api', rels))
    private_ip = hookenv.unit_private_ip()
    public_ip = hookenv.unit_public_ip()
    template_data['api_public_address'] = _bind_addr(public_ip)
    template_data['api_private_address'] = _bind_addr(private_ip)
    template_data['bind_address'] = '127.0.0.1'
    template_data['api_http_uri'] = 'http://%s:%s' % (private_ip, 8080)
    template_data['api_https_uri'] = 'https://%s:%s' % (private_ip, 6443)

    arch = subprocess.check_output(['dpkg', '--print-architecture']).strip()

    template_data['web_uri'] = '/kubernetes/%s/local/bin/linux/%s/' % (version,
                                                                       arch)
    if version == 'local':
        template_data['alias'] = hookenv.charm_dir() + '/files/output/'
    else:
        directory = '/opt/kubernetes/_output/local/bin/linux/%s/' % arch
        template_data['alias'] = directory
    _encode(template_data)
    return template_data
Esempio n. 42
0
def setup_mattermost_backend(postgres_relation):
    print("Configuring and starting backend service.")
    _configure_mattermost_postgres(postgres_relation.master.uri)
    service_restart('mattermost')
    # Set build number for Juju status
    try:
        output = check_output(
            ['/opt/mattermost/bin/platform', 'version'],
            cwd='/opt/mattermost/bin/',
            universal_newlines=True,
            stderr=STDOUT,
        )
    except CalledProcessError as e:
        print(e.output)
        raise
    build_number = re.search(r'Build Number: ([0-9]+.[0-9]+.[0-9])+\n', output).group(1)
    application_version_set(build_number)
    open_port(8065)
    # The next two aren't really open. This is a fix for the following issue:
    #    no expose possible before `open-port`.
    #    no `open-port` of 80 and 443 before ssl.
    #    no ssl certificate before `expose`.
    open_port(config().get('port'))
    open_port(443)
    status_set(
        'active',
        'Ready (http://{}:8065 [Insecure! Please set fqdn!])'.format(unit_public_ip()))
    set_state('mattermost.backend.started')
Esempio n. 43
0
def init_nextcloud(mysql):

    status_set('maintenance', "Initializing Nextcloud")

    ctxt = {'dbname': mysql.database(),
            'dbuser': mysql.user(),
            'dbpass': mysql.password(),
            'dbhost': mysql.host(),
            'dbport': mysql.port(),
            'dbtype': 'mysql',
            'admin_username': config().get('admin-username'),
            'admin_password': config().get('admin-password'),
            'data_dir': Path('/var/www/nextcloud/data'),
            }

    nextcloud_init = ("sudo -u www-data /usr/bin/php occ  maintenance:install "
                      "--database {dbtype} --database-name {dbname} "
                      "--database-host {dbhost} --database-pass {dbpass} "
                      "--database-user {dbuser} --admin-user {admin_username} "
                      "--admin-pass {admin_password} "
                      "--data-dir {data_dir} ").format(**ctxt)

    log(nextcloud_init)

    with chdir('/var/www/nextcloud'):
        subprocess.call("sudo chown -R www-data:www-data .".split())
        subprocess.call(nextcloud_init.split())

    Path('/var/www/nextcloud/config/config.php').write_text(
        Path('/var/www/nextcloud/config/config.php').open().read().replace(
            "localhost", config().get('fqdn') or unit_public_ip()))

    set_flag('nextcloud.initdone')

    status_set('active', "Nextcloud init complete")
Esempio n. 44
0
def create_csr(tls):
    '''Create a certificate signing request (CSR). Only the followers need to
    run this operation.'''
    if not is_leader():
        with chdir('easy-rsa/easyrsa3'):
            # Must remove the path characters from the unit name.
            path_name = hookenv.local_unit().replace('/', '_')
            # The reqest will be named with unit_name.req
            req_file = 'pki/reqs/{0}.req'.format(path_name)
            # If the request already exists do not generate another one.
            if os.path.isfile(req_file):
                remove_state('create certificate signing request')
                return

            # The Common Name is the public address of the system.
            cn = hookenv.unit_public_ip()
            hookenv.log('Creating the CSR for {0}'.format(path_name))
            sans = get_sans()
            # Create a CSR for this system with the subject and SANs.
            gen_req = './easyrsa --batch --req-cn={0} --subject-alt-name={1}' \
                      ' gen-req {2} nopass 2>&1'.format(cn, sans, path_name)
            check_call(split(gen_req))
            # Read the CSR file.
            with open(req_file, 'r') as fp:
                csr = fp.read()
            # Set the CSR on the relation object.
            tls.set_csr(csr)
    else:
        hookenv.log('The leader does not need to create a CSR.')
Esempio n. 45
0
def configure(force=False):
    config = hookenv.config()

    def changed(key):
        return force or config.changed(key)

    if config.changed('proxy') and config.get('proxy'):
        shutil.rmtree('/opt/collector-web')
        install()
        if hookenv.status_get() == 'blocked':
            return  # We're blocked again

    with open('/etc/graphite/local_settings.py', 'r+') as f:
        contents = f.read()
        contents = re.sub(r'#TIME_ZONE = .*', "TIME_ZONE = 'Etc/UTC'",
                          contents)
        f.seek(0, 0)
        f.truncate()
        f.write(contents)

    if 'juju-secret' not in config:
        return

    ini_path = '/opt/collector-web/production.ini'
    with open(ini_path, 'r') as f:
        ini = f.read()

    api_addresses = os.getenv('JUJU_API_ADDRESSES')
    if api_addresses:
        juju_api = 'wss://%s' % api_addresses.split()[0]
        ini = re.sub(r'juju.api.endpoint =.*',
                     'juju.api.endpoint = %s' % juju_api, ini)

    ini = re.sub(
        r'graphite.url =.*',
        'graphite.url = http://%s:9001' % hookenv.unit_get('public-address'),
        ini)

    if changed('juju-user'):
        ini = re.sub(
            r'juju.api.user =.*',
            'juju.api.user = %s' % config.get('juju-user') or '', ini)

    if changed('juju-secret'):
        ini = re.sub(
            r'juju.api.secret =.*',
            'juju.api.secret = %s' % config.get('juju-secret') or '', ini)

    if changed('publish-url'):
        ini = re.sub(
            r'publish.url =.*',
            'publish.url = %s' % config.get('publish-url') or '', ini)

    with open(ini_path, 'w') as f:
        f.write(ini)

    host.service_restart('collectorweb')
    hookenv.status_set('active',
                       'Ready http://%s:9000' % hookenv.unit_public_ip())
Esempio n. 46
0
def fiche_available():
    """Start or restart fiche, set status and state
    """
    start_restart()
    # Set status
    status_set('active', 'Fiche is active at: %s' %
               ("%s:%s" % (unit_public_ip(), config('fiche-server-port'))))
    set_state('fiche.available')
def configure_interface(saltinfo):
    config = hookenv.config()
    if config['use-dns']:
        address = socket.gethostname()
    else:
        address = unit_public_ip()
    port = None
    saltinfo.configure(address, port)
Esempio n. 48
0
def prepare_tls_certificates(tls):
    common_name = hookenv.unit_public_ip()
    sans = set()
    sans.add(hookenv.unit_public_ip())
    sans.update(get_ingress_addresses('db'))
    sans.update(get_ingress_addresses('cluster'))
    sans.add(socket.gethostname())

    # add cluster peers as alt names when present
    cluster = endpoint_from_flag('cluster.joined')
    if cluster:
        for ip in cluster.get_db_ingress_addresses():
            sans.add(ip)

    sans = sorted(sans)
    certificate_name = hookenv.local_unit().replace('/', '_')
    tls.request_server_cert(common_name, sans, certificate_name)
 def get_config_action(self):
     """Retrieve and return settings and key data for get-config action."""
     public_key = self.kv.get("public-key")
     port = (self.charm_config["listen-port"], )
     ip = hookenv.unit_public_ip()
     log("Returning configuration for action: {}, {}, {}".format(
         public_key, port, ip))
     return public_key, ip, port
Esempio n. 50
0
def request_server_certificates(tls, website):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()
    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        get_ingress_address(website),
        socket.gethostname(),
    ]
    # maybe they have extra names they want as SANs
    extra_sans = hookenv.config('extra_sans')
    if extra_sans and not extra_sans == "":
        sans.extend(extra_sans.split())
    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')
    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 51
0
def send_data(tls, kube_control):
    '''Send the data that is required to create a server certificate for
    this server.'''
    # Use the public ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_public_ip()

    ingress_ip = get_ingress_address(kube_control)

    # Create SANs that the tls layer will add to the server cert.
    sans = [
        hookenv.unit_public_ip(),
        ingress_ip,
        gethostname()
    ]

    # Create a path safe name by removing path characters from the unit name.
    certificate_name = hookenv.local_unit().replace('/', '_')

    # Request a server cert with this information.
    tls.request_server_cert(common_name, sans, certificate_name)
Esempio n. 52
0
def update_torrc():
    cfg = hookenv.config()
    render(
        source="torrc",
        target="/etc/tor/torrc",
        owner="root",
        perms=0o644,
        context={"cfg": cfg, "public_address": hookenv.unit_public_ip(), "private_address": hookenv.unit_private_ip()},
    )
    remove_state("tor.configured")
    set_state("tor.start")
Esempio n. 53
0
def setup():
    hookenv.status_set('maintenance', 'setting up mailinabox')
    password = "******"  # TODO: generate a decent password
    config = hookenv.config()
    setup_env = {}
    setup_env.update(os.environ)
    setup_env.update({
        'NONINTERACTIVE': '1',
        'DISABLE_FIREWALL': '1',  # Juju manages this
        'SKIP_NETWORK_CHECKS': '1',
        'PUBLIC_IP': hookenv.unit_public_ip(),
        'PUBLIC_IPV6': 'auto',
        'PRIMARY_HOSTNAME': config['hostname'],
        'EMAIL_ADDR': 'me@%s' % (config['hostname']),
        'EMAIL_PW': password,
    })
    hookenv.open_port(53, protocol='UDP')
    for port in (25, 80, 443, 587, 993, 4190):
        hookenv.open_port(port)
    check_call(['setup/start.sh'], shell=True, cwd=SRC_DIR, env=setup_env)
    set_state('mailinabox.setup')
    hookenv.status_set('active', 'Admin console: https://%s/admin' % (hookenv.unit_public_ip()))
Esempio n. 54
0
def install_site():
    if config('deploy_key') is not None:
        render(
            source='key',
            target='/root/.ssh/id_rsa',
            perms=0o600,
            context={
              'key': config('deploy_key')
            }
        )

    clone()
    if config('commit') is not None:
        update_to_commit()
    chown(config('app-path'), 'puma')

    domain = config('domain')
    if domain is None or domain == '':
        domain = unit_public_ip()
    render(source='puma.conf',
           target='/etc/init/puma.conf',
           owner='root',
           group='root',
           perms=0o644,
           context={
            'workers': config('web_workers'),
            'threads': config('worker_threads'),
            'app_path': config('app-path'),
            'secret_key_base': config('secret_key_base'),
            'domain': domain,
        })
    render(source='nginx.conf',
           target='/etc/nginx/sites-enabled/puma.conf',
           owner='root',
           group='root',
           perms=0o644,
           context={
            'port': config('web_port'),
            'app_path': config('app-path'),
        })
    open_port(config('web_port'))

    if service_running('nginx'):
        service_restart('nginx')
    else:
        service_start('nginx')
    chown(config('app-path'), 'puma')
    status_set('maintenance', '')
    set_state('app.installed')
Esempio n. 55
0
def rpc_broadcast_ip_address():
    c = config()
    # Pre-juju2, rpc_interface was used to control the interface used for
    # client communication.
    if c['rpc_interface'] or not hookenv.has_juju_version('2.3'):
        return (interface_to_ip(c['rpc_interface']) or
                hookenv.unit_public_ip())

    # Post-juju2, addresses for relation endpoints can be specified at deploy time
    # in a standard way, so listen_interface in config should be unnecessary.
    # Only the database endpoint is used, as Cassandra only supports a single
    # IP address to broadcast as the connection address.
    ip = hookenv.network_get('database')['ingress-addresses'][0]
    hookenv.log('rpc_broadcast_ip_address == {!r}'.format(ip), DEBUG)
    return ip
Esempio n. 56
0
def start(*args):
    cmd = "/home/{}/bin/service-openmano start".format(USER)
    out, err = _run(cmd)

    if not kvdb.get('openmano-tenant'):
        out, err = _run('./scripts/create-tenant.sh')
        kvdb.set('openmano-tenant', out.strip())

    status_set(
        'active',
        'Up on {host}:{port}'.format(
            host=hookenv.unit_public_ip(),
            port='9090'))

    set_state('openmano.running')
Esempio n. 57
0
def install_openvim_controller(mysql):
    create_openvim_user()
    download_openvim()
    add_openvim_to_path()
    configure_openvim(mysql)
    initialize_openvim_database(mysql)
    generate_ssh_key()
    install_openvim_service()
    start_openvim()
    create_sane_defaults()
    status_set(
        'active',
        'Up on {host}:{port}'.format(
            host=unit_public_ip(),
            port='9080'))
    set_state('openvim-controller.installed')
Esempio n. 58
0
def db_relation_joined():
    """
    Hook to run when somebody connects to us.

    """

    passwords = json.loads(leader_get('passwords'))  # TODO: Exception handling.

    relation_set(
        host=config('couchdb-host'),
        ip=unit_public_ip(),
        port=config('couchdb-port'),
        admin_pass=passwords['admin_pass'],
        repl_pass=passwords['repl_pass']
    )

    log("{} joined".format(os.getenv('ENSEMBLE_REMOTE_UNIT')), INFO)
Esempio n. 59
0
def _publish_database_relation(relid, superuser):
    # The Casandra service needs to provide a common set of credentials
    # to a client unit. The leader creates these, if none of the other
    # units are found to have published them already (a previously elected
    # leader may have done this). The leader then tickles the other units,
    # firing a hook and giving them the opportunity to copy and publish
    # these credentials.
    username, password = _client_credentials(relid)
    if username is None:
        if hookenv.is_leader():
            # Credentials not set. The leader must generate them. We use
            # the service name so that database permissions remain valid
            # even after the relation is dropped and recreated, or the
            # juju environment rebuild and the database restored from
            # backups.
            username = '******'.format(helpers.get_service_name(relid))
            if superuser:
                username += '_admin'
            password = host.pwgen()
            pwhash = helpers.encrypt_password(password)
            with helpers.connect() as session:
                helpers.ensure_user(session, username, pwhash, superuser)
            # Wake the peers, if any.
            helpers.leader_ping()
        else:
            return  # No credentials yet. Nothing to do.

    # Publish the information the client needs on the relation where
    # they can find it.
    #  - authentication credentials
    #  - address and port
    #  - cluster_name, so clients can differentiate multiple clusters
    #  - datacenter + rack, so clients know what names they can use
    #    when altering keyspace replication settings.
    config = hookenv.config()
    hookenv.relation_set(relid,
                         username=username, password=password,
                         host=hookenv.unit_public_ip(),
                         native_transport_port=config['native_transport_port'],
                         rpc_port=config['rpc_port'],
                         cluster_name=config['cluster_name'],
                         datacenter=config['datacenter'],
                         rack=config['rack'])