Beispiel #1
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl')
            or relations.endpoint_from_flag(
                'identity-service.available.ssl_legacy'))
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                if changed:
                    for ssl in ssl_objects:
                        self.set_state('ssl.requested', True)
                        self.configure_cert(ssl['cert'],
                                            ssl['key'],
                                            cn=ssl['cn'])
                        self.configure_ca(ssl['ca'])

                    if not os_utils.snap_install_requested():
                        self.configure_apache()

                    self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
def render_stuff(*args):
    """Render the configuration for Manila when all the interfaces are
    available.

    Note that the charm class actually calls on the manila-plugin directly to
    get the config, so we unconditionally clear the changed status here, if it
    was set.
    """
    with charms_openstack.charm.provide_charm_instance() as manila_charm:
        pre_ssl_enabled = manila_charm.get_state('ssl.enabled')
        tls = relations.endpoint_from_flag('certificates.available')
        manila_charm.configure_tls(certificates_interface=tls)
        if pre_ssl_enabled != manila_charm.get_state('ssl.enabled'):
            keystone = relations.endpoint_from_flag(
                'identity-service.available')
            manila_charm.register_endpoints(keystone)

        manila_charm.render_with_interfaces(args)
        manila_charm.assess_status()
        charms.reactive.set_state('manila.config.rendered')
        manila_plugin = \
            relations.endpoint_from_flag('manila-plugin.changed') or \
            relations.endpoint_from_flag('remote-manila-plugin.changed')
        if manila_plugin:
            manila_plugin.clear_changed()
        manila_charm.enable_webserver_site()
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')
def send_cell_data():
    ncc_ep = endpoint_from_flag('endpoint.nova-cell-compute.joined')
    amqp_conv = endpoint_from_flag('amqp.available').conversation()
    # Push this calculation of service names down into the interfaces
    amqp_service_names = [u.split('/')[0] for u in amqp_conv.units if u]
    db_conv = endpoint_from_flag('shared-db.available').conversation()
    db_service_names = [u.split('/')[0] for u in db_conv.units if u]
    ncc_ep.send_cell_data(hookenv.config('cell-name'), amqp_service_names[0],
                          db_service_names[0])
def configure_designate_basic(*args):
    """Configure the minimum to boostrap designate"""
    # If cluster relation is available it needs to passed in
    cluster = relations.endpoint_from_flag('cluster.available')
    if cluster is not None:
        args = args + (cluster, )
    dns_backend = relations.endpoint_from_flag('dns-backend.available')
    if dns_backend is not None:
        args = args + (dns_backend, )
    with provide_charm_instance() as instance:
        instance.render_base_config(args)
    reactive.set_state('base-config.rendered')
Beispiel #6
0
def kubernetes_status_update():
    kubernetes = endpoint_from_flag('endpoint.kubernetes.new-status')    
    k8s_status = kubernetes.get_status()
    if not k8s_status or not k8s_status['status']:
        return
    
    nodeport = None
    deployment_running = False
    # Check if service and deployment has been created on k8s
    # If the service is created, set the connection string
    # else clear it.
    for resource in k8s_status['status']:
        if resource['kind'] == "Service":
            nodeport = resource['spec']['ports'][0]['nodePort']
        elif resource['kind'] == "Deployment":
            if 'availableReplicas' in resource['status'] and \
                resource['status']['availableReplicas'] == \
                resource['status']['readyReplicas']:
                deployment_running = True
    kubernetes_workers = kubernetes.get_worker_ips()
    if nodeport and kubernetes_workers and deployment_running:
        unitdata.kv().set('kafka-connect-service',
                          kubernetes_workers[0] + ':' + str(nodeport))
        status.active('K8s deployment running')
        clear_flag('endpoint.kubernetes.new-status')
        set_flag('kafka-connect.running')
    else:
        unitdata.kv().set('kafka-connect-service', '')
        clear_flag('kafka-connect.running')
Beispiel #7
0
def publish_global_client_cert():
    """
    This is for backwards compatibility with older tls-certificate clients
    only.  Obviously, it's not good security / design to have clients sharing
    a certificate, but it seems that there are clients that depend on this
    (though some, like etcd, only block on the flag that it triggers but don't
    actually use the cert), so we have to set it for now.
    """
    if not client_approle_authorized():
        log("Vault not authorized: Skipping publish_global_client_cert",
            "WARNING")
        return
    cert_created = is_flag_set('charm.vault.global-client-cert.created')
    reissue_requested = is_flag_set('certificates.reissue.global.requested')
    tls = endpoint_from_flag('certificates.available')
    if not cert_created or reissue_requested:
        ttl = config()['default-ttl']
        max_ttl = config()['max-ttl']
        bundle = vault_pki.generate_certificate('client', 'global-client', [],
                                                ttl, max_ttl)
        unitdata.kv().set('charm.vault.global-client-cert', bundle)
        set_flag('charm.vault.global-client-cert.created')
        clear_flag('certificates.reissue.global.requested')
    else:
        bundle = unitdata.kv().get('charm.vault.global-client-cert')
    tls.set_client_cert(bundle['certificate'], bundle['private_key'])
Beispiel #8
0
def configure_vault(context):
    log("Running configure_vault", level=DEBUG)
    context['disable_mlock'] = is_container() or config('disable-mlock')

    context['ssl_available'] = is_state('vault.ssl.available')

    if is_flag_set('etcd.tls.available'):
        etcd = endpoint_from_flag('etcd.available')
        log("Etcd detected, adding to context", level=DEBUG)
        context['etcd_conn'] = etcd.connection_string()
        context['etcd_tls_ca_file'] = '/var/snap/vault/common/etcd-ca.pem'
        context['etcd_tls_cert_file'] = '/var/snap/vault/common/etcd-cert.pem'
        context['etcd_tls_key_file'] = '/var/snap/vault/common/etcd.key'
        save_etcd_client_credentials(etcd,
                                     key=context['etcd_tls_key_file'],
                                     cert=context['etcd_tls_cert_file'],
                                     ca=context['etcd_tls_ca_file'])
        context['api_addr'] = vault.get_api_url()
        context['cluster_addr'] = vault.get_cluster_url()
        log("Etcd detected, setting api_addr to {}".format(
            context['api_addr']))
    else:
        log("Etcd not detected", level=DEBUG)
    log("Rendering vault.hcl.j2", level=DEBUG)
    render('vault.hcl.j2', VAULT_CONFIG, context, perms=0o600)
    log("Rendering vault systemd configuation", level=DEBUG)
    render('vault.service.j2', VAULT_SYSTEMD_CONFIG, {}, perms=0o644)
    service('enable', 'vault')
    log("Opening vault port", level=DEBUG)
    open_port(8200)
    set_flag('configured')
    if any_file_changed([VAULT_CONFIG, VAULT_SYSTEMD_CONFIG]):
        # force a restart if config has changed
        clear_flag('started')
Beispiel #9
0
def create_cert_request():
    if not config.get('fqdns'):
        status_set('blocked', 'Waiting for fqdns config')
        return
    ssl_termination = endpoint_from_flag('endpoint.ssl-termination.available')

    upstream_config = config.get('upstreams').split(' ')
    upstreams = []

    for u in upstream_config:
        host, port = u.split(':')
        upstreams.append({
            'hostname': host,
            'port': port,
        })

    cert_request = {
        'fqdn': config.get('fqdns').rstrip().split(),
        'contact-email': config.get('contact-email', ''),
        'credentials': config.get('credentials', ''),
        'upstreams': upstreams,
        'nginx-config': parse_nginx_config(),
    }

    ssl_termination.send_cert_info(cert_request)
    status_set('waiting', 'Waiting for proxy to register certificate')
    set_flag('client.cert-requested')
Beispiel #10
0
def create_cert_request():
    if not config.get('fqdns'):
        status_set('blocked', 'Waiting for fqdns config')
        return
    ssl_termination = endpoint_from_flag('endpoint.ssl-termination.available')
    workers = get_worker_node_ips()
    if not workers:
        return
    upstreams = []
    ingress_nodeport = get_ingress_nodeport()
    for worker in workers:
        host = [{
            'hostname': worker,
            'private-address': worker,
            'port': ingress_nodeport
        }]
        upstreams.extend(host)
    print(upstreams)
    ssl_termination.send_cert_info({
        'fqdn':
        config.get('fqdns').rstrip().split(),
        'contact-email':
        config.get('contact-email', ''),
        'credentials':
        config.get('credentials', ''),
        'upstreams':
        upstreams,
    })
    status_set('waiting', 'Waiting for proxy to register certificate')
    set_flag('client.cert-requested')
Beispiel #11
0
def send_vault_url_and_ca():
    secrets = endpoint_from_flag('secrets.connected')
    vault_url_external = None
    if is_flag_set('ha.available'):
        hostname = config('hostname')
        if hostname:
            vault_url = vault.get_api_url(address=hostname)
        else:
            vip = vault.get_vip()
            vault_url = vault.get_api_url(address=vip)
            ext_vip = vault.get_vip(binding='external')
            if ext_vip and ext_vip != vip:
                vault_url_external = vault.get_api_url(address=ext_vip,
                                                       binding='external')
    else:
        vault_url = vault.get_api_url()
        vault_url_external = vault.get_api_url(binding='external')
        if vault_url_external == vault_url:
            vault_url_external = None

    secrets.publish_url(vault_url=vault_url, remote_binding='access')
    if vault_url_external:
        secrets.publish_url(vault_url=vault_url_external,
                            remote_binding='external')

    if config('ssl-ca'):
        secrets.publish_ca(vault_ca=config('ssl-ca'))
Beispiel #12
0
def send_vault_url_and_ca():
    secrets = endpoint_from_flag('secrets.connected')
    vault_url_external = None
    hostname = config('hostname')
    vip = vault.get_vip()
    if is_flag_set('ha.available'):
        if hostname:
            vault_url = vault.get_api_url(address=hostname)
        else:
            vault_url = vault.get_api_url(address=vip)
            ext_vip = vault.get_vip(binding='external')
            if ext_vip and ext_vip != vip:
                vault_url_external = vault.get_api_url(address=ext_vip,
                                                       binding='external')
    elif vip:
        log(
            "VIP is set but ha.available is not yet set, skipping "
            "send_vault_url_and_ca.",
            level=DEBUG)
        return
    else:
        vault_url = vault.get_api_url()
        vault_url_external = vault.get_api_url(binding='external')
        if vault_url_external == vault_url:
            vault_url_external = None

    secrets.publish_url(vault_url=vault_url, remote_binding='access')
    if vault_url_external:
        secrets.publish_url(vault_url=vault_url_external,
                            remote_binding='external')

    if config('ssl-ca'):
        secrets.publish_ca(vault_ca=config('ssl-ca'))
Beispiel #13
0
def create_certs():
    reissue_requested = is_flag_set('certificates.reissue.requested')
    tls = endpoint_from_flag('certificates.available')
    requests = tls.all_requests if reissue_requested else tls.new_requests
    if reissue_requested:
        log('Reissuing all certs')
    processed_applications = []
    for request in requests:
        log('Processing certificate request from {} for {}'.format(
            request.unit_name, request.common_name))
        if request.cert_type == 'application':
            cert_type = 'server'
            # When an application cert is published all units recieve the same
            # data so one need to process one request per application.
            if request.application_name in processed_applications:
                log('Already done {}'.format(request.application_name))
                continue
            else:
                processed_applications.append(request.application_name)
        else:
            cert_type = request.cert_type
        try:
            ttl = config()['default-ttl']
            max_ttl = config()['max-ttl']
            bundle = vault_pki.generate_certificate(cert_type,
                                                    request.common_name,
                                                    request.sans, ttl, max_ttl)
            request.set_cert(bundle['certificate'], bundle['private_key'])
        except vault.VaultInvalidRequest as e:
            log(str(e), level=ERROR)
            continue  # TODO: report failure back to client
    clear_flag('certificates.reissue.requested')
Beispiel #14
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl') or
            relations
            .endpoint_from_flag('identity-service.available.ssl_legacy'))
        certificates_interface = relations.endpoint_from_flag(
            'certificates.batch.cert.available')
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface,
            certificates_interface=certificates_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                # NOTE(fnordahl): regardless of changes to data we may
                # have other changes we want to apply to the files.
                # (e.g. ownership, permissions)
                #
                # Also note that c-h.host.write_file used in configure_cert()
                # has it's own logic to detect data changes.
                #
                # LP: #1821314
                for ssl in ssl_objects:
                    self.set_state('ssl.requested', True)
                    self.configure_cert(
                        ssl['cert'], ssl['key'], cn=ssl['cn'])
                    self.configure_ca(ssl['ca'])
                cert_utils.create_ip_cert_links(
                    os.path.join('/etc/apache2/ssl/', self.name))
                if not os_utils.snap_install_requested() and changed:
                    self.configure_apache()
                    ch_host.service_reload('apache2')

                self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
Beispiel #15
0
def configure_kafka_connect_base():
    kafka = endpoint_from_flag('kafka.ready')
    kubernetes = endpoint_from_flag('endpoint.kubernetes.available')

    kafka_brokers = []
    for kafka_unit in kafka.kafkas():
        kafka_brokers.append(kafka_unit['host'] + ':' + kafka_unit['port'])

    worker_config = generate_worker_config()
    worker_config['bootstrap.servers'] = ','.join(kafka_brokers)
    port = worker_config['rest.port'] if 'rest.port' in worker_config else 8083

    uuid = kubernetes.get_uuid()

    resource_context = {
        'configmap_name': 'cfgmap-{}'.format(uuid),
        'label': uuid,
        'properties': worker_config,
        'service_name': 'svc-{}'.format(uuid),
        'port': port,
        'deployment_name': 'depl-{}'.format(uuid),
        'replicas': conf.get('workers', 1),
        'container_name': uuid,
        'image': unitdata.kv().get('docker-image'),
        'containerport': port,
    }

    if data_changed('resource-context', resource_context):
        # Trigger a rolling update by setting a new annotation in the deployment
        resource_context['configmap_annotation'] = hashlib.sha1(datetime.datetime.now()
                                                                .isoformat()
                                                                .encode('utf-8')).hexdigest()
        templating.render(source="resources.j2",
                          target="/etc/kafka-connect/resources.yaml",
                          context=resource_context)

        
        resources = []
        with open('/etc/kafka-connect/resources.yaml', 'r') as f:
            docs = yaml.load_all(f)
            for doc in docs:
                resources.append(doc)
        kubernetes.send_create_request(resources)

    status.waiting('Waiting for k8s deployment (will happen in next hook)')
    set_flag('kafka-connect-base.configured')
Beispiel #16
0
 def send_storage_backend_data(self):
     cbend = relations.endpoint_from_flag('storage-backend.connected')
     cbend.configure_principal(backend_name=self.service_name,
                               configuration=self.cinder_configuration(),
                               stateless=self.stateless)
     # Add an assess status which will be picked up later by the atexit()
     # handler.
     self.assess_status()
Beispiel #17
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl')
            or relations.endpoint_from_flag(
                'identity-service.available.ssl_legacy'))
        certificates_interface = relations.endpoint_from_flag(
            'certificates.batch.cert.available')
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface,
            certificates_interface=certificates_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                # NOTE(fnordahl): regardless of changes to data we may
                # have other changes we want to apply to the files.
                # (e.g. ownership, permissions)
                #
                # Also note that c-h.host.write_file used in configure_cert()
                # has it's own logic to detect data changes.
                #
                # LP: #1821314
                for ssl in ssl_objects:
                    self.set_state('ssl.requested', True)
                    self.configure_cert(ssl['cert'], ssl['key'], cn=ssl['cn'])
                    self.configure_ca(ssl['ca'])
                cert_utils.create_ip_cert_links(
                    os.path.join('/etc/apache2/ssl/', self.name))
                if not os_utils.snap_install_requested() and changed:
                    self.configure_apache()
                    ch_host.service_reload('apache2')

                self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
Beispiel #18
0
def setup_rabbitmq():
    rabbitmq = endpoint_from_flag('rabbitmq.connected')
    juju_app_name = (MODEL_NAME.replace("/", '-') +
                     '.' +
                     JUJU_UNIT_NAME.split('/')[0])
    username = JUJU_UNIT_NAME.split('/')[0]
    vhost = '/' + juju_app_name
    rabbitmq.request_access(username, vhost)
    status.waiting('Waiting on RabbitMQ to configure vhost')
def send_compute_data():
    nc = endpoint_from_flag('endpoint.cloud-compute.joined')
    ncc_ep = endpoint_from_flag('endpoint.nova-cell-compute.changed')
    ncc_console_data = ncc_ep.get_console_data()
    ncc_network_data = ncc_ep.get_network_data()
    nc.set_network_data(
        ncc_network_data['quantum_url'],
        neutron_plugin=ncc_network_data['quantum_plugin'],
        network_manager=ncc_network_data['network_manager'],
        enable_security_groups=ncc_network_data['quantum_security_groups'])
    nc.set_console_data(
        serial_console_base_url=ncc_console_data['serial_console_base_url'],
        enable_serial_console=ncc_console_data['enable_serial_console'])
    nc.set_region(ncc_ep.get_region()['region'])
    nc.set_volume_data(ncc_ep.get_volume_data()['volume_service'])
    nc.set_ec2_data(ncc_ep.get_ec2_data()['ec2_host'])
    nc.trigger_remote_restart(
        restart_key=ncc_ep.get_restart_trigger()['restart_trigger'])
Beispiel #20
0
def configure_cinder_backup():
    # don't always have a relation context - obtain from the flag
    endp = endpoint_from_flag('endpoint.backup-backend.joined')
    with charms_openstack.charm.provide_charm_instance() as charm_instance:
        # publish config options for all remote units of a given rel
        name, config = charm_instance.get_swift_backup_config()
        endp.publish(name, config)
        charm_instance.configure_ca()
        flags.set_flag('config.complete')
Beispiel #21
0
 def send_storage_backend_data(self):
     cbend = relations.endpoint_from_flag('storage-backend.connected')
     cbend.configure_principal(
         backend_name=self.service_name,
         configuration=self.cinder_configuration(),
         stateless=self.stateless)
     # Add an assess status which will be picked up later by the atexit()
     # handler.
     self.assess_status()
Beispiel #22
0
def optional_interfaces(args, *interfaces):
    """Return a tuple with possible optional interfaces

    :param args: a list of reactive interfaces
    :param *interfaces: list of strings representing possible reactive
        interfaces.
    :returns: [list of reactive interfaces]
    """
    return args + tuple(ri for ri in (relations.endpoint_from_flag(i)
                                      for i in interfaces) if ri is not None)
Beispiel #23
0
def send_vault_url_and_ca():
    secrets = endpoint_from_flag('secrets.connected')
    if is_flag_set('ha.available'):
        vault_url = vault.get_api_url(address=config('vip'))
    else:
        vault_url = vault.get_api_url()
    secrets.publish_url(vault_url=vault_url)

    if config('ssl-ca'):
        secrets.publish_ca(vault_ca=config('ssl-ca'))
def configure_websso():
    # don't always have a relation context - obtain from the flag
    websso_fid_sp = endpoint_from_flag(
        'endpoint.websso-fid-service-provider.joined')
    with charm.provide_charm_instance() as charm_instance:
        # publish config options for all remote units of a given rel
        options = charm_instance.options
        websso_fid_sp.publish(options.protocol_name,
                              options.idp_name,
                              options.user_facing_name)
def update_status_info():
    endpoint = endpoint_from_flag('endpoint.kubernetes-deployer.available')
    status = check_predefined_resources()
    error_states = unitdata.kv().get('error-states', {})
    status.update(error_states)
    worker_ips = get_worker_node_ips()
    # Only report if the status has changed
    if (data_changed('status-info', status)
            or data_changed('worker-ips', worker_ips)):
        endpoint.send_status(status)
        endpoint.send_worker_ips(worker_ips)
def get_certificate_requests():
    endpoint = endpoint_from_flag('endpoint.ssl-termination.update')
    clear_flag('endpoint.ssl-termination.update')
    cert_requests = endpoint.get_cert_requests()
    if data_changed('sslterm.requests', cert_requests) and cert_requests:
        old_requests = unitdata.kv().get('sslterm.cert-requests', [])
        delete_old_certs(old_requests, cert_requests)
        unitdata.kv().set('sslterm.cert-requests', cert_requests)
        lets_encrypt.set_requested_certificates(cert_requests)
        set_flag('ssl-termination.waiting')
    clean_nginx('/etc/nginx/sites-available/ssl-termination')
Beispiel #27
0
def configure_dbd(mysql_endpoint):
    '''A dbd is only configured after leader election is
    performed and a database is believed to be configured'''
    hookenv.status_set('maintenance', 'Configuring slurm-dbd')

    is_active = dbd.is_active_dbd()

    role = dbd.ROLES[is_active]
    peer_role = dbd.ROLES[not is_active]

    dbd_conf = copy.deepcopy(hookenv.config())
    dbd_conf.update({
        'db_hostname': mysql_endpoint.db_host(),
        'db_port': dbd.MYSQL_DB_PORT,
        'db_password': mysql_endpoint.password(),
        'db_name': mysql_endpoint.database(),
        'db_username': mysql_endpoint.username(),
    })

    ha_endpoint = relations.endpoint_from_flag('endpoint.slurm-dbd-ha.joined')
    if ha_endpoint:
        net_details = dbd.add_key_prefix(ha_endpoint.network_details(), role)
        dbd_conf.update(net_details)

        # add prefixed peer data
        peer_data = dbd.add_key_prefix(ha_endpoint.peer_data, peer_role)
        dbd_conf.update(peer_data)
    else:
        # if running in standalone mode, just use network-get with HA endpoint
        # name to get an ingress address and a hostname
        net_details = dbd.add_key_prefix(dbd.network_details(), role)
        dbd_conf.update(net_details)
        peer_data = None

    # a dbd service is configurable if it is an active dbd
    # or a backup dbd that knows about an active dbd
    is_configurable = is_active or (not is_active and peer_data)
    if is_configurable:
        hookenv.log('dbd is configurable ({})'.format(role))
        # Setup slurm dirs and config
        dbd.render_slurmdbd_config(context=dbd_conf)
        # Render a minimal dummy slurm.conf
        dbd.render_slurm_config(context=dbd_conf)
        # Make sure slurmctld is running
        if not host.service_running(dbd.SLURMDBD_SERVICE):
            host.service_start(dbd.SLURMDBD_SERVICE)
        flags.set_flag('slurm-dbd.configured')
        flags.clear_flag('slurm-dbd.standalone_startup')
        host.service_restart(dbd.SLURMDBD_SERVICE)
    else:
        hookenv.log('dbd is NOT configurable ({})'.format(role))
        if not is_active:
            hookenv.status_set('maintenance',
                               'Backup dbd is waiting for peer data')
Beispiel #28
0
 def custom_assess_status_check(self):
     if not hookenv.config('nameservers'):
         return 'blocked', ('nameservers must be set')
     invalid_dns = self.options.invalid_pool_config()
     if invalid_dns:
         return 'blocked', invalid_dns
     dns_backend_available = (
         relations.endpoint_from_flag('dns-backend.available'))
     if not (dns_backend_available or hookenv.config('dns-slaves')):
         return 'blocked', ('Need either a dns-backend relation or '
                            'config(dns-slaves) or both.')
     return None, None
def send_k8s_request():
    if not config.get('fqdns'):
        status_set('blocked', 'Waiting for fqdns config')
        return
    if not config.get('nodeport'):
        status_set('blocked', 'Waiting for nodeport config')
        return
    endpoint = endpoint_from_flag('endpoint.kubernetes-deployer.available')
    context = {'name': application_name(), 'fqdns': config.get('fqdns'), 'nodeport': config.get('nodeport')}
    resource = render('resource.yaml', None, context)
    endpoint.send_create_request([yaml.load(resource)])
    set_flag('client.k8s-requested')
Beispiel #30
0
def create_topics():
    if not os.path.exists('/usr/lib/kafka/bin'):
        status.blocked('Could not find Kafka library, make sure the Kafka Connect charm is colocated with a Kafka unit.')
        return
    kafka = endpoint_from_flag('kafka.ready')
    zookeepers = []
    for zookeeper in kafka.zookeepers():
        zookeepers.append(zookeeper['host'] + ":" + zookeeper['port'])
    if not zookeepers:
        return
    # Set replication factor as number of Kafka brokers
    # Use the zookeeper-shell because Juju sets the Kafka
    # broker info one hook at a time and therefore we do not 
    # know beforehand howmany brokers there are    
    p = Popen(['/usr/lib/kafka/bin/zookeeper-shell.sh',
                   zookeepers[0]],
               stdin=PIPE, 
               stdout=PIPE)
    output = p.communicate(b'ls /brokers/ids')[0]
    # The broker info is in the last line between [id1,id2,id3]
    replication_factor = output.decode('utf-8') \
                               .strip() \
                               .split('\n')[-1] \
                               .count(',') \
                               + 1
    topics_suffixes = ['connectconfigs', 'connectoffsets', 'connectstatus']
    partitions = [1, 50, 10] # Best effort partition numbers
    model = os.environ['JUJU_MODEL_NAME']
    app = os.environ['JUJU_UNIT_NAME'].split('/')[0]
    prefix = "{}.{}.".format(model, app)
    for (suffix, partitions) in zip(topics_suffixes, partitions):
        topic = prefix + suffix
        unitdata.kv().set(suffix, topic)
        if topic_exists(topic, zookeepers):
            continue
        try:
            output = run(['/usr/lib/kafka/bin/kafka-topics.sh',
                          '--zookeeper',
                          ",".join(zookeepers),
                          "--create",
                          "--topic",
                          topic,
                          "--partitions",
                          str(partitions),
                          "--replication-factor",
                          str(replication_factor,
                          "--config",
                          "cleanup.policy=compact")], stdout=PIPE)
            output.check_returncode()
        except CalledProcessError as e:
            log(e)
    set_flag('kafka-connect-base.topic-created')
Beispiel #31
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl') or
            relations
            .endpoint_from_flag('identity-service.available.ssl_legacy'))
        certificates_interface = relations.endpoint_from_flag(
            'certificates.batch.cert.available')
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface,
            certificates_interface=certificates_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                if changed:
                    for ssl in ssl_objects:
                        self.set_state('ssl.requested', True)
                        self.configure_cert(
                            ssl['cert'], ssl['key'], cn=ssl['cn'])
                        self.configure_ca(ssl['ca'])
                    cert_utils.create_ip_cert_links(
                        os.path.join('/etc/apache2/ssl/', self.name))
                    if not os_utils.snap_install_requested():
                        self.configure_apache()
                        ch_host.service_reload('apache2')

                    self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
def create_client_cert():
    """Create client certificates with the request information from the
    relation object."""

    tls = endpoint_from_flag("client.client.certs.requested")

    # Iterate over all new requests
    for request in tls.new_client_requests:
        # Create a client certificate for this request.
        name = request.common_name
        client_cert, client_key = create_client_certificate(name)
        # Set the client certificate and key on the relationship object.
        request.set_cert(client_cert, client_key)
Beispiel #33
0
def check_cert_created():
    ssl_termination = endpoint_from_flag('endpoint.ssl-termination.update')
    status = ssl_termination.get_status()

    # Only one fqdn will be returned for shared certs.
    # If any fqdn match, the cert has been created.
    match_fqdn = config.get('fqdns').rstrip().split()
    for unit_status in status:
        for fqdn in unit_status['status']:
            if fqdn in match_fqdn:
                status_set('active', 'Ready')
                set_flag('client.cert-created')
                clear_flag('endpoint.ssl-termination.update')
Beispiel #34
0
    def __resolve_cluster(self):
        """ Resolve what the cluster adapter is.

        LY: The cluster interface only gets initialised if there are more
        than one unit in a cluster, however, a cluster of one unit is valid
        for the Openstack API charms. So, create and populate the 'cluster'
        namespace with data for a single unit if there are no peers.

        :returns: cluster adapter or None
        """
        smm = PeerHARelationAdapter(relation_name='cluster').single_mode_map
        if smm:
            return smm
        else:
            # LY: Automatically add the cluster relation if it exists and
            # has not been passed through.
            cluster_rel = relations.endpoint_from_flag('cluster.connected')
            if cluster_rel:
                return PeerHARelationAdapter(relation=cluster_rel)
        return None
Beispiel #35
0
#!/usr/bin/env python3
import sys
sys.path.append('lib')

# Make sure that reactive is bootstrapped and all the states are setup
# properly
from charms.layer import basic
basic.bootstrap_charm_deps()
basic.init_config_states()

import charm.openstack.tempest as tempest
import charms.reactive.relations as relations
import charmhelpers.core.hookenv as hookenv


if __name__ == '__main__':
    identity_int = relations.endpoint_from_flag('identity-admin.available')
    if identity_int is None:
        # The interface isn't connected, so we can't do this yet
        hookenv.action_fail(
            "The identity-admin interface is not available - bailing")
    else:
        tempest.render_configs([identity_int])
        tempest.run_test('smoke')