def run_che():
    status_set('maintenance', 'Installing Eclipse Che')
    # Start and stop Che so che's config is generated
    start_che()
    stop_che()
    # Add Juju stuff to Che config
    json_add_object_to_array(
        "{}/templates/stack-juju-charm.json".format(charm_dir()),
        "/home/ubuntu/instance/data/stacks/stacks.json"
    )
    copyfile(
        "{}/templates/type-juju.svg".format(charm_dir()),
        "/home/ubuntu/instance/data/stacks/images/type-juju.svg"
    )
    json_add_object_to_array(
        "{}/templates/project-template-charms.json".format(charm_dir()),
        "/home/ubuntu/instance/data/templates/samples.json"
    )
    json_add_object_to_array(
        "{}/templates/project-template-interface.json".format(charm_dir()),
        "/home/ubuntu/instance/data/templates/samples.json"
    )
    json_add_object_to_array(
        "{}/templates/project-template-layer.json".format(charm_dir()),
        "/home/ubuntu/instance/data/templates/samples.json"
    )
    # Start Che for real
    start_che()
    # opened ports are used by `juju expose` so It's important to open all
    # ports a user connects to.
    open_port('8080', protocol="TCP")           # Port to the UI
    open_port('32768-65535', protocol="TCP")    # Ports to the workspaces
    status_set('active', 'Ready (eclipse/che)')
    set_state('che.available')
Beispiel #2
0
def install():
    """Install http-test"""
    #subprocess.check_call(['hostnamectl', 'set-hostname', 'http-test'])
    try:
        # update needed because of weird error
        hookenv.log("Installing dependencies")
        subprocess.check_output(['apt-get', 'update'])
        subprocess.check_output(['pip3', 'install', 'Flask',])
    except subprocess.CalledProcessError as exception:
        hookenv.log(exception.output)
        exit(1)
    mergecopytree(charm_dir() + '/files/http-test', "/opt/http-test")
    hookenv.log("Extracting and moving required files and folders")
    hookenv.log("Generating upstart file")
    with open(charm_dir()+'/templates/upstart.conf', 'r') as upstart_t_file:
        upstart_template = upstart_t_file.read()
    with open('/etc/init/http-test.conf', 'w') as upstart_file:
        upstart_file = upstart_file.write(upstart_template)
    hookenv.log("Starting http-test service")
    try:
        subprocess.check_output(['service', 'http-test', 'start'])
    except subprocess.CalledProcessError as exception:
        hookenv.log(exception.output)
        exit(1)
    open_port(5000)
    status_set('active', 'Ready')
    set_state('http-test.installed')
def install():
    juju_log('**********install.real')
    rsync(
        charm_dir() + '/packages/vsm-dep-repo',
        '/opt'
    )
    rsync(
        charm_dir() + '/packages/vsmrepo',
        '/opt'
    )
    rsync(
        charm_dir() + '/files/apt.conf',
        '/etc/apt'
    )
    rsync(
        charm_dir() + '/files/vsm.list',
        '/etc/apt/sources.list.d'
    )
    rsync(
        charm_dir() + '/files/vsm-dep.list',
        '/etc/apt/sources.list.d'
    )
    apt_update()
    apt_install(VSM_PACKAGES)
    juju_log('**********finished to install vsm vsm-dashboard python-vsmclient')
    add_source(config('ceph-source'), config('ceph-key'))
    apt_update(fatal=True)
    apt_install(packages=PRE_INSTALL_PACKAGES, fatal=True)
Beispiel #4
0
def installoracle():
    hookenv.log('Installing Oracle JDK')
    filesdir = '{}/files/'.format(charm_dir())
    conf = hookenv.config()
    (tarname, dirname) = get_java_paths(filesdir, conf['install-type'], conf['java-major'])
    destdir = "/opt/java/{}".format(dirname)
    if not os.path.isdir(destdir):
        tfile = tarfile.open(
            '{}/files/{}'.format(charm_dir(), tarname), 'r')
        # Important to note that the following extraction is
        # UNSAFE since .tar.gz archive could contain
        # relative path like ../../ and overwrite other dirs
        extractdir = '{}/{}'.format(filesdir, dirname)
        tfile.extractall(filesdir)
        mergecopytree(extractdir, destdir)
        # Set defaults
        subprocess.check_output(['update-alternatives', '--install', '/usr/bin/java', 'java', '{}/jre/bin/java'.format(destdir), '2000'])
        subprocess.check_output(['update-alternatives', '--install', '/usr/bin/javac', 'javac', '{}/bin/javac'.format(destdir), '2000'])
        # set env vars
        with utils.environment_edit_in_place('/etc/environment') as env:
            # ensure that correct java is used
            env['JAVA_HOME'] = destdir
            env['J2SDKDIR'] = destdir
            env['J2REDIR'] = '{}/jre'.format(destdir)
            env['DERBY_HOME'] = '{}/db'.format(destdir)
            if destdir not in env['PATH']:
                env['PATH'] = ':'.join([
                    '{}/bin'.format(env['JAVA_HOME']),
                    '{}/bin'.format(env['J2REDIR']),
                    '{}/bin'.format(env['DERBY_HOME']),
                    env['PATH'],
                ])
Beispiel #5
0
def install():
    """Install REST2JFed"""
    try:
        # update needed because of weird error
        hookenv.log("Installing dependencies")
        subprocess.check_output(['apt-get', 'update'])
        subprocess.check_output(['pip2', 'install', 'Jinja2', 'Flask', 'pyyaml', 'click', 'python-dateutil'])
    except subprocess.CalledProcessError as exception:
        hookenv.log(exception.output)
        exit(1)
    hookenv.log("Extracting and moving required files and folders")
    mergecopytree(charm_dir() + '/files/jfedS4', "/opt/jfedS4")
    mergecopytree(charm_dir() + '/files/rest2jfed', "/opt/rest2jfed")
    hookenv.log("Generating upstart file")
    with open(charm_dir()+'/templates/upstart.conf', 'r') as upstart_t_file:
        upstart_template = upstart_t_file.read()
    with open('/etc/init/rest2jfed.conf', 'w') as upstart_file:
        upstart_file = upstart_file.write(upstart_template)
    hookenv.log("Starting rest2jfed service")
    try:
        subprocess.check_output(['service', 'rest2jfed', 'start'])
    except subprocess.CalledProcessError as exception:
        hookenv.log(exception.output)
        exit(1)
    open_port(5000)
    status_set('active', 'Ready')
    set_state('rest2jfed.installed')
Beispiel #6
0
def report_consolidated_health():
    cache_file = path(hookenv.charm_dir()) / 'unit_addresses'
    results = {
        'service': 'cloudfoundry',
        'health': 'pass',
        'state': hookenv.juju_status(),
        'units': {},
    }
    if cache_file.exists():
        units = yaml.safe_load(cache_file.text())
        for unit, address in units.iteritems():
            unit_dash = unit.replace('/', '-')
            output = subprocess.check_output([
                'ssh', '-q', 'root@{}'.format(address),
                '-i', path(hookenv.charm_dir()) / 'orchestrator-key',
                '-o', 'UserKnownHostsFile=/dev/null',
                '-o', 'StrictHostKeyChecking=no',
                ' ; '.join([
                    'export CHARM_DIR=/var/lib/juju/agents/unit-{}/charm'.format(unit_dash),
                    'cd $CHARM_DIR',
                    'hooks/health',
                ]),
            ])
            results['units'][unit] = yaml.safe_load(output)
            health = results['units'][unit]['health']
            if health == 'fail':
                results['health'] = 'fail'
            elif health == 'warn' and results['health'] != 'fail':
                results['health'] = 'warn'
    print yaml.safe_dump(results, default_flow_style=False)
def _fetch_oracle_jre():
    config = hookenv.config()
    url = config.get('private_jre_url', None)
    if url and config.get('retrieved_jre', None) != url:
        filename = os.path.join(hookenv.charm_dir(),
                                'lib', url.split('/')[-1])
        if not filename.endswith('-linux-x64.tar.gz'):
            helpers.status_set('blocked',
                               'Invalid private_jre_url {}'.format(url))
            raise SystemExit(0)
        helpers.status_set(hookenv.status_get(),
                           'Downloading Oracle JRE')
        hookenv.log('Oracle JRE URL is {}'.format(url))
        urllib.request.urlretrieve(url, filename)
        config['retrieved_jre'] = url

    pattern = os.path.join(hookenv.charm_dir(),
                           'lib', 'server-jre-?u*-linux-x64.tar.gz')
    tarballs = glob.glob(pattern)
    if not (url or tarballs):
        helpers.status_set('blocked',
                           'private_jre_url not set and no local tarballs.')
        raise SystemExit(0)

    elif not tarballs:
        helpers.status_set('blocked',
                           'Oracle JRE tarball not found ({})'.format(pattern))
        raise SystemExit(0)

    # Latest tarball by filename/version num. Lets hope they don't hit
    # 99 (currently at 76).
    tarball = sorted(tarballs)[-1]
    return tarball
Beispiel #8
0
def install_kafka_connector():
    server_path = "/opt/wso2esb/wso2esb-{}/repository/deployment/server".format(ESB_VERSION)

    # copy connector
    synapse_libs_path = '{}/synapse-libs'.format(server_path)
    if not os.path.exists(synapse_libs_path):
        os.makedirs(synapse_libs_path)
    shutil.copy(charm_dir() + '/files/kafka-connector-%s.zip' % KAFKA_CONNECTOR_VERSION, synapse_libs_path)
    os.chown(
        charm_dir() + '/files/kafka-connector-%s.zip' % KAFKA_CONNECTOR_VERSION,
        pwd.getpwnam("esbuser").pw_uid,
        grp.getgrnam("wso2").gr_gid
    )

    # enable connector
    kafka_enable_path = "{}/synapse-configs/default/imports/".format(server_path)
    if not os.path.exists(kafka_enable_path):
        os.makedirs(kafka_enable_path)
    templating.render(
        source='{org.wso2.carbon.connector}kafka.xml',
        target='%s/{org.wso2.carbon.connector}kafka.xml' % kafka_enable_path,
        context={},
        owner='esbuser',
        group='wso2',
    )
    # Wait for kafka connector to come online
    time.sleep(20)

    # Copy sequence
    kafka_hostname = relation_get('private-address')
    kafka_topic = "test"
    sequence_path = "{}/synapse-configs/default/sequences".format(server_path)
    if not os.path.exists(sequence_path):
        os.makedirs(sequence_path)
    templating.render(
        source='postTopic.xml',
        target='{}/postTopic.xml'.format('/opt/wso2esb'),
        context={
            'kafka_broker': kafka_hostname,
            'kafka_topic': kafka_topic,
        },
        owner='esbuser',
        group='wso2',
    )
    shutil.move('/opt/wso2esb/postTopic.xml', sequence_path + '/postTopic.xml')

    # Copy API
    api_path = "{}/synapse-configs/default/api".format(server_path)
    if not os.path.exists(api_path):
        os.makedirs(api_path)
    templating.render(
        source='kafka.xml',
        target='{}/kafka.xml'.format(api_path),
        context={},
        owner='esbuser',
        group='wso2',
    )
def additional_install_locations(plugin, source):
    '''
    Add any required additional package locations for the charm, based
    on the Neutron plugin being used. This will also force an immediate
    package upgrade.
    '''
    release = get_os_codename_install_source(source)
    if plugin == 'Calico':
        if config('calico-origin'):
            calico_source = config('calico-origin')
        elif release in ('icehouse', 'juno', 'kilo'):
            # Prior to the Liberty release, Calico's Nova and Neutron changes
            # were not fully upstreamed, so we need to point to a
            # release-specific PPA that includes Calico-specific Nova and
            # Neutron packages.
            calico_source = 'ppa:project-calico/%s' % release
        else:
            # From Liberty onwards, we can point to a PPA that does not include
            # any patched OpenStack packages, and hence is independent of the
            # OpenStack release.
            calico_source = 'ppa:project-calico/stable'

        add_source(calico_source)

    elif plugin == 'midonet':
        midonet_origin = config('midonet-origin')
        release_num = midonet_origin.split('-')[1]

        if midonet_origin.startswith('mem'):
            with open(os.path.join(charm_dir(),
                                   'files/midokura.key')) as midokura_gpg_key:
                priv_gpg_key = midokura_gpg_key.read()
            mem_username = config('mem-username')
            mem_password = config('mem-password')
            if release in ('juno', 'kilo', 'liberty'):
                add_source(
                    'deb http://%s:%[email protected]/openstack/%s/stable '
                    'trusty main' % (mem_username, mem_password, release),
                    key=priv_gpg_key)
            add_source('http://%s:%[email protected]/midonet/v%s/stable '
                       'main' % (mem_username, mem_password, release_num),
                       key=priv_gpg_key)
        else:
            with open(os.path.join(charm_dir(),
                                   'files/midonet.key')) as midonet_gpg_key:
                pub_gpg_key = midonet_gpg_key.read()
            if release in ('juno', 'kilo', 'liberty'):
                add_source(
                    'deb http://repo.midonet.org/openstack-%s stable main' %
                    release, key=pub_gpg_key)

            add_source('deb http://repo.midonet.org/midonet/v%s stable main' %
                       release_num, key=pub_gpg_key)

        apt_update(fatal=True)
        apt_upgrade(fatal=True)
    def test_preinstall(self, check_call):
        # Noop if there are no preinstall hooks found running the
        # install hook.
        hookenv.hook_name.return_value = 'install'
        actions.preinstall('')
        self.assertFalse(check_call.called)
        hookenv.log.assert_any_call('No preinstall hooks found')

        # If preinstall hooks are found running the install hook,
        # the preinstall hooks are run.
        hook_dirs = []
        hook_files = []
        for i in range(1, 3):
            hook_dirs.append(os.path.join(hookenv.charm_dir(),
                                          'exec.d', str(i)))
            hook_files.append(os.path.join(hook_dirs[-1], 'charm-pre-install'))

            os.makedirs(hook_dirs[-1])
            with open(hook_files[-1], 'w') as f1:
                print('mocked', file=f1)
            os.chmod(hook_files[-1], 0o755)

        check_call.reset_mock()
        actions.preinstall('')

        calls = [call(['sh', '-c', f2]) for f2 in hook_files]
        check_call.assert_has_calls(calls)

        # If a preinstall hook is not executable, a warning is raised.
        hook_dir = os.path.join(hookenv.charm_dir(), 'exec.d', '55')
        hook_file = os.path.join(hook_dir, 'charm-pre-install')
        os.makedirs(hook_dir)
        with open(hook_file, 'w') as f1:
            print('whoops', file=f1)
        os.chmod(hook_file, 0o644)
        check_call.reset_mock()
        hookenv.log.reset_mock()
        actions.preinstall('')
        check_call.assert_has_calls(calls)  # Only previous hooks run.
        hookenv.log.assert_has_calls([
            call(ANY),
            call(ANY),
            call(ANY, hookenv.WARNING)])

        # Nothing happens if the install hook is not being run.
        hookenv.hook_name.return_value = 'config-changed'
        check_call.reset_mock()
        actions.preinstall('')
        self.assertFalse(check_call.called)
Beispiel #11
0
def git_clone_and_install(file_name, core_project):
    """Clone/install all OpenStack repos specified in yaml config file."""
    global requirements_dir

    if file_name == "None":
        return

    yaml_file = os.path.join(charm_dir(), file_name)

    # clone/install the requirements project first
    installed = _git_clone_and_install_subset(yaml_file,
                                              whitelist=['requirements'])
    if 'requirements' not in installed:
        error_out('requirements git repository must be specified')

    # clone/install all other projects except requirements and the core project
    blacklist = ['requirements', core_project]
    _git_clone_and_install_subset(yaml_file, blacklist=blacklist,
                                  update_requirements=True)

    # clone/install the core project
    whitelist = [core_project]
    installed = _git_clone_and_install_subset(yaml_file, whitelist=whitelist,
                                              update_requirements=True)
    if core_project not in installed:
        error_out('{} git repository must be specified'.format(core_project))
def init_config_states():
    import yaml
    from charmhelpers.core import hookenv
    from charms.reactive import set_state
    from charms.reactive import toggle_state

    config = hookenv.config()

    config_defaults = {}
    config_defs = {}
    config_yaml = os.path.join(hookenv.charm_dir(), 'config.yaml')
    if os.path.exists(config_yaml):
        with open(config_yaml) as fp:
            config_defs = yaml.safe_load(fp).get('options', {})
            config_defaults = {
                key: value.get('default')
                for key, value in config_defs.items()
            }
    for opt in config_defs.keys():
        if config.changed(opt):
            set_state('config.changed')
            set_state('config.changed.{}'.format(opt))
        toggle_state('config.set.{}'.format(opt), config.get(opt))
        toggle_state('config.default.{}'.format(opt),
                     config.get(opt) == config_defaults[opt])
    hookenv.atexit(clear_config_states)
Beispiel #13
0
def render_files(reldata=None):
    '''Use jinja templating to render the docker-compose.yml and master.json
    file to contain the dynamic data for the configuration files.'''
    context = {}
    # Load the context data with SDN data.
    context.update(gather_sdn_data())
    # Add the charm configuration data to the context.
    context.update(hookenv.config())
    if reldata:
        connection_string = reldata.get_connection_string()
        # Define where the etcd tls files will be kept.
        etcd_dir = '/etc/ssl/etcd'
        # Create paths to the etcd client ca, key, and cert file locations.
        ca = os.path.join(etcd_dir, 'client-ca.pem')
        key = os.path.join(etcd_dir, 'client-key.pem')
        cert = os.path.join(etcd_dir, 'client-cert.pem')
        # Save the client credentials (in relation data) to the paths provided.
        reldata.save_client_credentials(key, cert, ca)
        # Update the context so the template has the etcd information.
        context.update({'etcd_dir': etcd_dir,
                        'connection_string': connection_string,
                        'etcd_ca': ca,
                        'etcd_key': key,
                        'etcd_cert': cert})

    charm_dir = hookenv.charm_dir()
    rendered_kube_dir = os.path.join(charm_dir, 'files/kubernetes')
    if not os.path.exists(rendered_kube_dir):
        os.makedirs(rendered_kube_dir)
    rendered_manifest_dir = os.path.join(charm_dir, 'files/manifests')
    if not os.path.exists(rendered_manifest_dir):
        os.makedirs(rendered_manifest_dir)

    # Update the context with extra values, arch, manifest dir, and private IP.
    context.update({'arch': arch(),
                    'master_address': leader_get('master-address'),
                    'manifest_directory': rendered_manifest_dir,
                    'public_address': hookenv.unit_get('public-address'),
                    'private_address': hookenv.unit_get('private-address')})

    # Adapted from: http://kubernetes.io/docs/getting-started-guides/docker/
    target = os.path.join(rendered_kube_dir, 'docker-compose.yml')
    # Render the files/kubernetes/docker-compose.yml file that contains the
    # definition for kubelet and proxy.
    render('docker-compose.yml', target, context)

    if is_leader():
        # Source: https://github.com/kubernetes/...master/cluster/images/hyperkube  # noqa
        target = os.path.join(rendered_manifest_dir, 'master.json')
        # Render the files/manifests/master.json that contains parameters for
        # the apiserver, controller, and controller-manager
        render('master.json', target, context)
        # Source: ...cluster/addons/dns/skydns-svc.yaml.in
        target = os.path.join(rendered_manifest_dir, 'kubedns-svc.yaml')
        # Render files/kubernetes/kubedns-svc.yaml for the DNS service.
        render('kubedns-svc.yaml', target, context)
        # Source: ...cluster/addons/dns/skydns-rc.yaml.in
        target = os.path.join(rendered_manifest_dir, 'kubedns-rc.yaml')
        # Render files/kubernetes/kubedns-rc.yaml for the DNS pod.
        render('kubedns-rc.yaml', target, context)
Beispiel #14
0
def install():
    """
    Install jenkins-job-builder from a archive, remote git repository or a
    locally bundled copy shipped with the charm.  Any locally bundled copy
    overrides 'jjb-install-source' setting.
    """
    if not os.path.isdir(CONFIG_DIR):
        os.mkdir(CONFIG_DIR)
    src = config('jjb-install-source')
    tarball = os.path.join(charm_dir(), 'files', TARBALL)

    if os.path.isfile(tarball):
        log('Installing jenkins-job-builder from bundled file: %s.' % tarball)
        install_from_file(tarball)
    elif src.startswith('git://'):
        log('Installing jenkins-job-builder from remote git: %s.' % src)
        install_from_git(src)
    elif src == 'distro':
        log('Installing jenkins-job-builder from Ubuntu archive.')
        if lsb_release()['DISTRIB_CODENAME'] in ['precise', 'quantal']:
            m = ('jenkins-job-builder package only available in Ubuntu 13.04 '
                 'and later.')
            raise Exception(m)
        apt_update(fatal=True)
        apt_install(['jenkins-job-builder', 'python-pbr'],
                    fatal=True)
    else:
        m = ('Must specify a git url as install source or bundled source with '
             'the charm.')
        log(m, ERROR)
        raise Exception(m)
Beispiel #15
0
    def render_checks(self, creds):
        render(source='keystone.yaml',
               target=self.oscreds,
               context=creds,
               owner='nagios',
               group='nagios')

        nrpe = NRPE()
        if not os.path.exists(self.plugins_dir):
            os.makedirs(self.plugins_dir)

        charm_plugin_dir = os.path.join(hookenv.charm_dir(), 'files',
                                        'plugins/')
        host.rsync(charm_plugin_dir,
                   self.plugins_dir,
                   options=['--executability'])

        contrail_check_command = os.path.join(self.plugins_dir,
                                              'check_contrail_alarms.py')
        nrpe.add_check(
            shortname='contrail_alarms',
            description='Check Contrail alarms',
            check_cmd=contrail_check_command,
        )

        nrpe.write()
Beispiel #16
0
def render_files(reldata=None):
    '''Use jinja templating to render the docker-compose.yml and master.json
    file to contain the dynamic data for the configuration files.'''
    context = {}
    # Load the context manager with sdn and config data.
    context.update(gather_sdn_data())
    context.update(hookenv.config())
    if reldata:
        context.update({'connection_string': reldata.connection_string()})
    charm_dir = hookenv.charm_dir()
    rendered_kube_dir = os.path.join(charm_dir, 'files/kubernetes')
    if not os.path.exists(rendered_kube_dir):
        os.makedirs(rendered_kube_dir)
    rendered_manifest_dir = os.path.join(charm_dir, 'files/manifests')
    if not os.path.exists(rendered_manifest_dir):
        os.makedirs(rendered_manifest_dir)
    # Add the manifest directory so the docker-compose file can have.
    context.update({'manifest_directory': rendered_manifest_dir,
                    'private_address': hookenv.unit_get('private-address')})

    # Render the files/kubernetes/docker-compose.yml file that contains the
    # definition for kubelet and proxy.
    target = os.path.join(rendered_kube_dir, 'docker-compose.yml')
    render('docker-compose.yml', target, context)
    # Render the files/manifests/master.json that contains parameters for the
    # apiserver, controller, and controller-manager
    target = os.path.join(rendered_manifest_dir, 'master.json')
    render('master.json', target, context)
    # Render files/kubernetes/skydns-svc.yaml for SkyDNS service
    target = os.path.join(rendered_manifest_dir, 'skydns-svc.yml')
    render('skydns-svc.yml', target, context)
    # Render files/kubernetes/skydns-rc.yaml for SkyDNS pods
    target = os.path.join(rendered_manifest_dir, 'skydns-rc.yml')
    render('skydns-rc.yml', target, context)
Beispiel #17
0
def upgrade_limeds():
    stop_limeds()
    hookenv.status_set('maintenance', 'Upgrading LimeDS')
    keypath = '{}/files/id_rsa'.format(hookenv.charm_dir())
    subprocess.check_call(['chmod', 'go-r', keypath])
    subprocess.check_call(
        [
            # use ssh-agent to use supplied privkey for git ssh connection
            'ssh-agent',
            'bash',
            '-c',
            # remote 'upstream' will point to supplied given repo
            'ssh-add {}; git pull upstream master'.format(keypath)
        ],
        cwd='/opt/limeds')
    try:
        subprocess.check_output(['gradle', 'jar', 'export'],
                                cwd='/opt/limeds',
                                stderr=subprocess.STDOUT,
                                universal_newlines=True)
    except subprocess.CalledProcessError as error:
        hookenv.status_set(
            'blocked', 'Error while building gradle: {}'.format(error.output))
        exit()
    start_limeds()
    hookenv.status_set('active', 'Ready')
def install():
    status_set('maintenance', 'Executing pre-install')
    execd_preinstall()
    configure_installation_source(config('openstack-origin'))

    status_set('maintenance', 'Installing apt packages')
    apt_update()
    apt_install(determine_packages(), fatal=True)

    if placement_api_enabled():
        disable_package_apache_site()

    git_install(config('openstack-origin-git'))

    _files = os.path.join(charm_dir(), 'files')
    if os.path.isdir(_files):
        for f in os.listdir(_files):
            f = os.path.join(_files, f)
            if os.path.isfile(f):
                log('Installing %s to /usr/bin' % f)
                shutil.copy2(f, '/usr/bin')
    [open_port(port) for port in determine_ports()]
    msg = 'Disabling services into db relation joined'
    log(msg)
    status_set('maintenance', msg)
    disable_services()
    cmd_all_services('stop')
Beispiel #19
0
def install(sojobo):
    api_dir = list(sojobo.connection())[0]['api-dir']
    copyfile('{}/files/controller_aws.py'.format(charm_dir()), '{}/controllers/controller_aws.py'.format(api_dir))
    chownr(api_dir, 'sojobo', 'www-data', chowntopdir=True)
    service_restart('nginx')
    status_set('active', 'data copied')
    set_state('controller-aws.installed')
Beispiel #20
0
def cache_unit_addresses(s):
    units = {}
    for rid in sorted(hookenv.relation_ids(OrchestratorRelation.name)):
        for unit in sorted(hookenv.related_units(rid)):
            units[unit] = hookenv.relation_get('private-address', unit, rid)
    cache_file = path(hookenv.charm_dir()) / 'unit_addresses'
    cache_file.write_text(yaml.safe_dump(units, default_flow_style=False))
Beispiel #21
0
def file_from_template(tmpl, dest, searchList):
    template_file = os.path.join(charm_dir(), "templates", tmpl)
    t = Template(file=template_file, searchList=searchList)
    with open(dest, "w") as f:
        f.write(juju_header())
        f.write(str(t))
    os.chmod(dest, 0444)
Beispiel #22
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)
Beispiel #23
0
def add_client_authorization():
    """easyrsa has a default OpenSSL configuration that does not support
    client authentication. Append "clientAuth" to the server ssl certificate
    configuration. This is not default, to enable this in your charm set the
    reactive state 'tls.client.authorization.required'.
    """
    if not is_leader():
        return
    else:
        hookenv.log("Configuring SSL PKI for clientAuth")

    # Get the absolute path to the charm directory.
    charm_dir = hookenv.charm_dir()
    # Create the relative path to the server file.
    server_file = "easy-rsa/easyrsa3/x509-types/server"
    # Use an absolute path so current directory does not affect the result.
    openssl_config = os.path.join(charm_dir, server_file)
    hookenv.log("Updating {0}".format(openssl_config))
    # Read the file in.
    with open(openssl_config, "r") as f:
        existing_template = f.readlines()

    # Enable client and server authorization for certificates
    xtype = [w.replace("serverAuth", "serverAuth, clientAuth") for w in existing_template]  # noqa
    # Write the configuration file back out.
    with open(openssl_config, "w+") as f:
        f.writelines(xtype)

    set_state("tls.client.authorization.added")
Beispiel #24
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
Beispiel #25
0
def manage():
    if hookenv.hook_name() == 'health':
        report_consolidated_health()
        return
    manager = services.ServiceManager([
        {
            'service': 'bundle',
            'required_data': [
                JujuAPICredentials(),
                ArtifactsCache(),
            ],
            'data_ready': [
                cache_unit_addresses,
                precache_job_artifacts,
                generate,
                deploy,
            ],
            'start': [],
            'stop': [],
        },
        {
            'service': 'nginx',
            'required_data': [{'charm_dir': hookenv.charm_dir(),
                               'config': hookenv.config()}],
            'provided_data': [OrchestratorRelation()],
            'data_ready': [
                services.render_template(
                    source='nginx.conf',
                    target='/etc/nginx/sites-enabled/artifact_proxy'),
            ],
        },
    ])
    manager.manage()
Beispiel #26
0
 def register(cls, filepath):
     if filepath not in Handler._HANDLERS:
         _filepath = os.path.relpath(filepath, hookenv.charm_dir())
         if LOG_OPTS['register']:
             hookenv.log('Registering external reactive handler for %s' % _filepath, level=hookenv.DEBUG)
         Handler._HANDLERS[filepath] = cls(filepath)
     return Handler._HANDLERS[filepath]
Beispiel #27
0
def tensorflow_available(tf):
    addrs = tf.addrs()
    if not addrs:
        if host.service_running('tfdemo'):
            host.service_stop('tfdemo')
        return
    hookenv.open_port(8080)
    ctx = {
        'addr': ','.join(addrs),
    }
    samples_dir = os.path.join(hookenv.charm_dir(), "samples")
    if os.path.exists(samples_dir):
        ctx['samples'] = samples_dir
    render(
        source="tfdemo.service",
        target="/etc/systemd/system/tfdemo.service",
        owner="root",
        perms=0o644,
        context=ctx,
    )
    check_call(['systemctl', 'daemon-reload'])
    if host.service_running('tfdemo'):
        host.service_restart('tfdemo')
    else:
        host.service_start('tfdemo')
    remove_state('client.available')
Beispiel #28
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
Beispiel #29
0
def _finalize():
    if _statuses['_initialized']:
        # If we haven't been initialized, we can't truly be finalized.
        # This makes things more efficient if an action sets a status
        # but subsequently starts the reactive bus.
        _statuses['_finalized'] = True
    charm_name = hookenv.charm_name()
    charm_dir = Path(hookenv.charm_dir())
    with charm_dir.joinpath('layer.yaml').open() as fp:
        includes = yaml.safe_load(fp.read()).get('includes', [])
    layer_order = includes + [charm_name]

    for workload_state in WorkloadState:
        if workload_state not in _statuses:
            continue
        if not _statuses[workload_state]:
            continue

        def _get_key(record):
            layer_name, message = record
            if layer_name in layer_order:
                return layer_order.index(layer_name)
            else:
                return 0

        sorted_statuses = sorted(_statuses[workload_state], key=_get_key)
        layer_name, message = sorted_statuses[-1]
        _status_set_immediate(workload_state, message)
        break
def install_ssh_keys():
    '''Installs configured ssh keys + known hosts for accessing lp branches'''
    priv_key = config('ssh-privkey')
    pub_key = config('ssh-pubkey')
    if not priv_key or not pub_key:
        log('Missing SSH keys in charm config, will not install.')
        return

    ssh_dir = os.path.join('/home', CI_USER, '.ssh')
    if not os.path.isdir(ssh_dir):
        os.mkdir(ssh_dir)

    _priv_key = os.path.join(ssh_dir, 'id_rsa')
    _pub_key = os.path.join(ssh_dir, 'id_rsa.pub')
    with open(_priv_key, 'w') as out:
        out.write(priv_key)
    with open(_pub_key, 'w') as out:
        out.write(pub_key)

    # ssh keys are used to branch from LP. install bazaar.launchpad.net's
    # host keys, as well.
    lp_kh = os.path.join(charm_dir(), 'known_host_keys')
    if lp_kh:
        with open(os.path.join(ssh_dir, 'known_hosts'), 'w') as out:
            out.write(open(lp_kh).read())

    subprocess.check_call(['chmod', '0600', _priv_key])
    subprocess.check_call(['chown', '-R', CI_USER, ssh_dir])

    log('*** Installed ssh keys for user %s to %s' % (CI_USER, ssh_dir))
Beispiel #31
0
def render_files(reldata=None):
    '''Use jinja templating to render the docker-compose.yml and master.json
    file to contain the dynamic data for the configuration files.'''
    context = {}
    # Load the context data with SDN data.
    context.update(gather_sdn_data())
    # Add the charm configuration data to the context.
    context.update(hookenv.config())
    if reldata:
        connection_string = reldata.get_connection_string()
        # Define where the etcd tls files will be kept.
        etcd_dir = '/etc/ssl/etcd'
        # Create paths to the etcd client ca, key, and cert file locations.
        ca = os.path.join(etcd_dir, 'client-ca.pem')
        key = os.path.join(etcd_dir, 'client-key.pem')
        cert = os.path.join(etcd_dir, 'client-cert.pem')
        # Save the client credentials (in relation data) to the paths provided.
        reldata.save_client_credentials(key, cert, ca)
        # Update the context so the template has the etcd information.
        context.update({'etcd_dir': etcd_dir,
                        'connection_string': connection_string,
                        'etcd_ca': ca,
                        'etcd_key': key,
                        'etcd_cert': cert})

    charm_dir = hookenv.charm_dir()
    rendered_kube_dir = os.path.join(charm_dir, 'files/kubernetes')
    if not os.path.exists(rendered_kube_dir):
        os.makedirs(rendered_kube_dir)
    rendered_manifest_dir = os.path.join(charm_dir, 'files/manifests')
    if not os.path.exists(rendered_manifest_dir):
        os.makedirs(rendered_manifest_dir)

    # Update the context with extra values, arch, manifest dir, and private IP.
    context.update({'arch': arch(),
                    'master_address': leader_get('master-address'),
                    'manifest_directory': rendered_manifest_dir,
                    'public_address': hookenv.unit_get('public-address'),
                    'private_address': hookenv.unit_get('private-address')})

    # Adapted from: http://kubernetes.io/docs/getting-started-guides/docker/
    target = os.path.join(rendered_kube_dir, 'docker-compose.yml')
    # Render the files/kubernetes/docker-compose.yml file that contains the
    # definition for kubelet and proxy.
    render('docker-compose.yml', target, context)

    if is_leader():
        # Source: https://github.com/kubernetes/...master/cluster/images/hyperkube  # noqa
        target = os.path.join(rendered_manifest_dir, 'master.json')
        # Render the files/manifests/master.json that contains parameters for
        # the apiserver, controller, and controller-manager
        render('master.json', target, context)
        # Source: ...cluster/addons/dns/skydns-svc.yaml.in
        target = os.path.join(rendered_manifest_dir, 'kubedns-svc.yaml')
        # Render files/kubernetes/kubedns-svc.yaml for the DNS service.
        render('kubedns-svc.yaml', target, context)
        # Source: ...cluster/addons/dns/skydns-rc.yaml.in
        target = os.path.join(rendered_manifest_dir, 'kubedns-rc.yaml')
        # Render files/kubernetes/kubedns-rc.yaml for the DNS pod.
        render('kubedns-rc.yaml', target, context)
Beispiel #32
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
Beispiel #33
0
def get_conf():
    defaults = os.path.join(hookenv.charm_dir(), 'files', 'default.json')
    with open(defaults) as fh:
        data = json.loads(fh.read())

    config = hookenv.config()
    log_level = config.get('log-level')
    if log_level.lower() not in ('debug', 'warning', 'error', 'info'):
        hookenv.log(
            'invalid log level config %s' % log_level,
            hookenv.WARNING)
        log_level = 'debug'

    data['datacenter'] = os.environ.get("JUJU_ENV_NAME", "dc1")
    data['node_name'] = hookenv.local_unit().replace('/', '-')
    data['domain'] = config.get('domain')
    data['log_level'] = log_level.lower()

    #data['key_file'] = ""
    #data['ca_file'] = ""
    #data['cert_file'] = ""
    #data['verify_incoming'] = True
    #data['verify_outgoing'] = True

    return data
def install():
    hookenv.status_set('maintenance', 'Executing pre-install')
    execd.execd_preinstall()
    ch_utils.configure_installation_source(hookenv.config('openstack-origin'))

    hookenv.status_set('maintenance', 'Installing apt packages')
    ch_fetch.apt_update()
    ch_fetch.apt_install(ncc_utils.determine_packages(), fatal=True)

    ncc_utils.disable_package_apache_site()
    ncc_utils.stop_deprecated_services()

    _files = os.path.join(hookenv.charm_dir(), 'files')
    if os.path.isdir(_files):
        for f in os.listdir(_files):
            f = os.path.join(_files, f)
            if os.path.isfile(f):
                hookenv.log('Installing %s to /usr/bin' % f)
                shutil.copy2(f, '/usr/bin')
    for port in ncc_utils.determine_ports():
        hookenv.open_port(port)
    msg = 'Disabling services into db relation joined'
    hookenv.log(msg)
    hookenv.status_set('maintenance', msg)
    if not ch_utils.is_unit_paused_set():
        for svc in ncc_utils.services():
            ch_host.service_pause(svc)
    else:
        hookenv.log('Unit is in paused state, not issuing stop/pause '
                    'to all services')
Beispiel #35
0
    def test_nrpe_external_master_relation(self, local_plugins_dir, nrpe,
                                           write_file, cassandra_version,
                                           mountpoint):
        mountpoint.side_effect = os.path.dirname
        cassandra_version.return_value = '2.2'
        # The fake charm_dir() needs populating.
        plugin_src_dir = os.path.join(os.path.dirname(__file__),
                                      os.pardir, 'files')
        shutil.copytree(plugin_src_dir,
                        os.path.join(hookenv.charm_dir(), 'files'))

        with tempfile.TemporaryDirectory() as d:
            local_plugins_dir.return_value = d
            actions.nrpe_external_master_relation('')

            # The expected file was written to the expected filename
            # with required perms.
            with open(os.path.join(plugin_src_dir, 'check_cassandra_heap.sh'),
                      'rb') as f:
                write_file.assert_called_once_with(
                    os.path.join(d, 'check_cassandra_heap.sh'), f.read(),
                    perms=0o555)

            nrpe().add_check.assert_has_calls([
                call(shortname='cassandra_heap',
                     description='Check Cassandra Heap',
                     check_cmd='check_cassandra_heap.sh localhost 80 90'),
                call(description=('Check Cassandra Disk '
                                  '/var/lib/cassandra'),
                     shortname='cassandra_disk_var_lib_cassandra',
                     check_cmd=('check_disk -u GB -w 50% -c 25% -K 5% '
                                '-p /var/lib/cassandra'))],
                any_order=True)

            nrpe().write.assert_called_once_with()
 def __call__(self, manager, service_name, event_name):
     """Open unit ports."""
     service = manager.get_service(service_name)
     new_ports = service.get("ports", [])
     port_file = os.path.join(hookenv.charm_dir(),
                              ".{}.ports".format(service_name))
     if os.path.exists(port_file):
         with open(port_file) as fp:
             old_ports = fp.read().split(",")
         for old_port in old_ports:
             if bool(old_port) and not self.ports_contains(
                     old_port, new_ports):
                 hookenv.close_port(old_port)
     with open(port_file, "w") as fp:
         fp.write(",".join(str(port) for port in new_ports))
     for port in new_ports:
         # A port is either a number or 'ICMP'
         protocol = "TCP"
         if str(port).upper() == "ICMP":
             protocol = "ICMP"
         if event_name == "start":
             try:
                 hookenv.open_port(port, protocol)
             except subprocess.CalledProcessError as err:
                 if err.returncode == 1:
                     hookenv.log(
                         "open_port returns: {}, ignoring".format(err),
                         level=hookenv.INFO,
                     )
                 else:
                     raise
         elif event_name == "stop":
             hookenv.close_port(port, protocol)
def install_app():
    """ Performs application installation
    """

    hookenv.log('Installing Huginn', 'info')

    # Configure NGINX vhost
    nginxlib.configure_site('default', 'vhost.conf',
                            app_path=ruby_dist_dir())

    # Update application
    huginnlib.download_archive()
    shell("mkdir -p %s/{log,tmp/pids,tmp/sockets}" % (ruby_dist_dir()))
    shell("cp %(dir)s/config/unicorn.rb.example "
          "%(dir)s/config/unicorn.rb" % {'dir': ruby_dist_dir()})

    bundle("install --deployment --without development test")
    procfile = path.join(hookenv.charm_dir(), 'templates/Procfile')
    shell("cp %(procfile)s %(dir)s/Procfile" % {
        'procfile': procfile,
        'dir': ruby_dist_dir()
    })

    bundle("exec rake assets:precompile RAILS_ENV=production")

    host.service_restart('nginx')
    hookenv.status_set('active', 'Huginn is installed!')
def install():
    hookenv.status_set('maintenance', 'Executing pre-install')
    execd.execd_preinstall()
    ch_utils.configure_installation_source(hookenv.config('openstack-origin'))

    hookenv.status_set('maintenance', 'Installing apt packages')
    ch_fetch.apt_update()
    ch_fetch.apt_install(ncc_utils.determine_packages(), fatal=True)

    ncc_utils.disable_package_apache_site()
    ncc_utils.stop_deprecated_services()

    _files = os.path.join(hookenv.charm_dir(), 'files')
    if os.path.isdir(_files):
        for f in os.listdir(_files):
            f = os.path.join(_files, f)
            if os.path.isfile(f):
                hookenv.log('Installing %s to /usr/bin' % f)
                shutil.copy2(f, '/usr/bin')
    for port in ncc_utils.determine_ports():
        hookenv.open_port(port)
    msg = 'Disabling services into db relation joined'
    hookenv.log(msg)
    hookenv.status_set('maintenance', msg)
    if not ch_utils.is_unit_paused_set():
        for svc in ncc_utils.services():
            ch_host.service_pause(svc)
    else:
        hookenv.log('Unit is in paused state, not issuing stop/pause '
                    'to all services')
Beispiel #39
0
def config_changed():
    # setup identity to reach private LP resources
    common.ensure_user()
    common.install_ssh_keys()

    lp_user = config('lp-login')
    if lp_user:
        cmd = ['bzr', 'launchpad-login', lp_user]
        common.run_as_user(cmd=cmd, user=common.CI_USER)

    # NOTE: this will overwrite existing configs so relation hooks will have to
    # re-run in order for settings to be re-applied.
    bundled_repo = os.path.join(charm_dir(), common.LOCAL_CONFIG_REPO)
    conf_repo = config('config-repo')
    conf_repo_rcs = config('config-repo-rcs')
    if os.path.exists(bundled_repo) and os.path.isdir(bundled_repo):
        common.update_configs_from_charm(bundled_repo)
        run_relation_hooks()
    elif is_valid_config_repo(conf_repo_rcs, conf_repo):
        common.update_configs_from_repo(conf_repo_rcs,
                                        conf_repo,
                                        config('config-repo-revision'))
        run_relation_hooks()

    if config('schedule-updates'):
        schedule = config('update-frequency')
        cron.schedule_repo_updates(
            schedule, common.CI_USER, common.CI_CONFIG_DIR, conf_repo_rcs,
            jjb.JOBS_CONFIG_DIR)
Beispiel #40
0
def add_client_authorization():
    '''easyrsa has a default OpenSSL configuration that does not support
    client authentication. Append "clientAuth" to the server ssl certificate
    configuration. This is not default, to enable this in your charm set the
    reactive state 'tls.client.authorization.required'.
    '''
    if not is_leader():
        return
    else:
        hookenv.log('Configuring SSL PKI for clientAuth')

    # Get the absolute path to the charm directory.
    charm_dir = hookenv.charm_dir()
    # Create the relative path to the server file.
    server_file = 'easy-rsa/easyrsa3/x509-types/server'
    # Use an absolute path so current directory does not affect the result.
    openssl_config = os.path.join(charm_dir, server_file)
    hookenv.log('Updating {0}'.format(openssl_config))
    # Read the file in.
    with open(openssl_config, 'r') as f:
        existing_template = f.readlines()

    # Enable client and server authorization for certificates
    xtype = [
        w.replace('serverAuth', 'serverAuth, clientAuth')
        for w in existing_template
    ]  # noqa
    # Write the configuration file back out.
    with open(openssl_config, 'w+') as f:
        f.writelines(xtype)

    set_state('tls.client.authorization.added')
Beispiel #41
0
def install_charm_files(service_name):
    """ Install files shipped with charm """
    nag_dirs = [
        '/etc/nagios/nrpe.d/', '/usr/local/lib/nagios/plugins',
        '/var/lib/nagios/export/'
    ]
    for nag_dir in nag_dirs:
        if not os.path.exists(nag_dir):
            host.mkdir(nag_dir, perms=0o755)
    charm_file_dir = os.path.join(hookenv.charm_dir(), 'files')
    charm_plugin_dir = os.path.join(charm_file_dir, 'plugins')
    pkg_plugin_dir = '/usr/lib/nagios/plugins/'
    local_plugin_dir = '/usr/local/lib/nagios/plugins/'

    shutil.copy2(os.path.join(charm_file_dir, 'nagios_plugin.py'),
                 pkg_plugin_dir + '/nagios_plugin.py')
    shutil.copy2(os.path.join(charm_file_dir, 'default_rsync'),
                 '/etc/default/rsync')
    shutil.copy2(os.path.join(charm_file_dir, 'rsyncd.conf'),
                 '/etc/rsyncd.conf')
    host.rsync(charm_plugin_dir,
               '/usr/local/lib/nagios/',
               options=['--executability'])
    if not os.path.exists(local_plugin_dir + 'nagios_plugin.py'):
        os.symlink(pkg_plugin_dir + 'nagios_plugin.py',
                   local_plugin_dir + 'nagios_plugin.py')
Beispiel #42
0
def install():
    """
    Install jenkins-job-builder from a archive, remote git repository or a
    locally bundled copy shipped with the charm.  Any locally bundled copy
    overrides 'jjb-install-source' setting.
    """
    if not os.path.isdir(CONFIG_DIR):
        os.mkdir(CONFIG_DIR)
    src = config('jjb-install-source')
    tarball = os.path.join(charm_dir(), 'files', TARBALL)

    if os.path.isfile(tarball):
        log('Installing jenkins-job-builder from bundled file: %s.' % tarball)
        install_from_file(tarball)
    elif src.startswith('git://'):
        log('Installing jenkins-job-builder from remote git: %s.' % src)
        install_from_git(src)
    elif src == 'distro':
        log('Installing jenkins-job-builder from Ubuntu archive.')
        if lsb_release()['DISTRIB_CODENAME'] in ['precise', 'quantal']:
            m = ('jenkins-job-builder package only available in Ubuntu 13.04 '
                 'and later.')
            raise Exception(m)
        apt_update(fatal=True)
        apt_install(['jenkins-job-builder', 'python-pbr'], fatal=True)
    else:
        m = ('Must specify a git url as install source or bundled source with '
             'the charm.')
        log(m, ERROR)
        raise Exception(m)
Beispiel #43
0
def server_key(source, destination, user=None, group=None):
    """
    Copy the server key to the destination, creating directories if needed and
    assign ownership if set.

    :param string source: The directory to look for the key, if None the key
    will be copied from default location.
    :param string destination: The path to save the key.
    :param string user: The optional name of the user to own the key.
    :param string group: The optional name of the group to own key.
    """
    _ensure_directory(destination, user, group)

    if not source:
        # Must remove the path characters from the local unit name.
        key_name = local_unit().replace('/', '_')
        # The location of server key is easy-rsa/easyrsa3/pki/private
        source = \
            os.path.join(
                charm_dir(),
                'easy-rsa/easyrsa3/pki/private/{0}.key'.format(key_name))

    # Copy the key to the destination.
    copy2(source, destination)
    chown(destination, user, group)

    # Set the destination path for the client key path on the unitdata.
    unitdata.kv().set('server-key-path', destination)
Beispiel #44
0
def _policy_success_file():
    """Return the file name for a successful drop of policy.d overrides

    :returns: the path name for the file.
    :rtype: str
    """
    return os.path.join(hookenv.charm_dir(), POLICYD_SUCCESS_FILENAME)
Beispiel #45
0
def server_cert(source, destination, user=None, group=None):
    """
    Copy the server certificate to the destination, creating directories if
    needed and assign ownership if set.

    :param string source: The directory to look for the certificate, if None
    the certificate will be copied from unit data.
    :param string destination: The path to save the certificate.
    :param string user: The optional name of the user to own the certificate.
    :param string group: The optional name of the group to own certificate.
    """
    _ensure_directory(destination, user, group)

    if not source:
        # Must remove the path characters from the local unit name.
        key_name = local_unit().replace('/', '_')
        # The location of server certificate is easy-rsa/easyrsa3/pki/issued
        source = \
            os.path.join(
                charm_dir(),
                'easy-rsa/easyrsa3/pki/issued/{0}.crt'.format(key_name))

    if os.path.isfile(source):
        # Copy the server certificate to the destination.
        copy2(source, destination)
    else:
        # No source server certificate, get the value from unit data.
        server_cert_key = 'tls.server.certificate'
        # Save the certificate data to the destination directory.
        _save_unitdata(server_cert_key, destination)

    chown(destination, user, group)
    # Set the destination path for the client certificate path on the unitdata.
    unitdata.kv().set('server-cert-path', destination)
 def __call__(self, manager, service_name, event_name):
     service = manager.get_service(service_name)
     # turn this generator into a list,
     # as we'll be going over it multiple times
     new_ports = list(service.get('ports', []))
     port_file = os.path.join(hookenv.charm_dir(),
                              '.{}.ports'.format(service_name))
     if os.path.exists(port_file):
         with open(port_file) as fp:
             old_ports = fp.read().split(',')
         for old_port in old_ports:
             if bool(old_port) and not self.ports_contains(
                     old_port, new_ports):
                 hookenv.close_port(old_port)
     with open(port_file, 'w') as fp:
         fp.write(','.join(str(port) for port in new_ports))
     for port in new_ports:
         # A port is either a number or 'ICMP'
         protocol = 'TCP'
         if str(port).upper() == 'ICMP':
             protocol = 'ICMP'
         if event_name == 'start':
             hookenv.open_port(port, protocol)
         elif event_name == 'stop':
             hookenv.close_port(port, protocol)
Beispiel #47
0
    def install(self, service=False):
        '''
        Attempts to install jar to path if checksum if different or
        does not exists.
        '''

        # Install debian file
        check_call([
            'apt', 'install', '-y',
            '{}/files/exporter.deb'.format(hookenv.charm_dir())
        ])

        if service:
            # Install as a service
            if hookenv.config()['public']:
                addr = '0.0.0.0'
            else:
                addr = hookenv.unit_private_ip()

            ex = ' '.join([
                shutil.which(EXPORTER_UNIT),
                '{addr}:{port}'.format(addr=addr, port=EXPORTER_PORT),
                EXPORTER_CONFIG_PATH
            ])

            templating.render(source='{}'.format(EXPORTER_SERVICE),
                              target=EXPORTER_SERVICE_PATH,
                              owner='root',
                              perms=0o400,
                              context={'exporter_path': ex})

            self.enable()
Beispiel #48
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.')
Beispiel #49
0
def zookeeper_changed(zookeeper):
    hookenv.log('Checking if Zookeeper has changed')
    zookeeper_servers_string = ''
    filesdir = '{}/files'.format(hookenv.charm_dir())
    for zk_unit in zookeeper.zookeepers():
        zookeeper_servers_string += '{}:{},'.format(zk_unit['host'],
                                                    zk_unit['port'])
    if zookeeper_servers_string[:-1] not in open(
            '{}/nifi-1.3.0/conf/nifi.properties'.format(filesdir)).read():
        hookenv.status_set(
            'maintenance',
            'Zookeeper has changed. Updating Apache NiFi settings and restarting'
        )
        re_edit_in_place(
            '{}/nifi-1.3.0/conf/nifi.properties'.format(filesdir), {
                r'.*nifi.zookeeper.connect.string.*':
                'nifi.zookeeper.connect.string={}'.format(
                    zookeeper_servers_string[:-1])
            })
        try:
            subprocess.check_call([
                'bash', '{}/nifi-1.3.0/bin/nifi.sh'.format(filesdir), 'restart'
            ])
            hookenv.status_set('active',
                               'Running: cluster mode with Zookeeper')
            set_state('apache-nifi.cluster')
        except subprocess.CalledProcessError:
            hookenv.status_set('blocked', 'Failed to restart')
def install_deployer():
    # Create user and configuration dir
    distconfig = utils.DistConfig(filename=charm_dir() + '/files/setup.yaml')
    distconfig.add_users()
    distconfig.add_dirs()
    # General deployer options
    deployers_path = '/home/kubedeployer/.config/kubedeployers'
    deployer_path = deployers_path + '/' + os.environ[
        'JUJU_UNIT_NAME'].replace('/', '-')
    # Save then in the kv store
    namespace_selector = 'ns'
    unitdata.kv().set('deployers_path', deployers_path)
    unitdata.kv().set('deployer_path', deployer_path)
    unitdata.kv().set('juju_app_selector', 'juju-app')
    unitdata.kv().set('deployer_selector', 'deployer')
    unitdata.kv().set('namespace_selector', namespace_selector)
    # Setup dir structure
    log('Setting up deployer dirs in: ' + deployer_path)
    global_dirs = ['namespaces', 'network-policies']
    for gd in global_dirs:
        if not os.path.exists(deployers_path + '/' + gd):
            os.makedirs(deployers_path + '/' + gd)
    dirs = ['resources']
    for d in dirs:
        if not os.path.exists(deployer_path + '/' + d):
            os.makedirs(deployer_path + '/' + d)
    # Setup the default namespace
    add_label_to_resource('default', namespace_selector + '=default',
                          'namespace', 'default', True)
    set_flag('deployer.installed')
Beispiel #51
0
def _short_action_id(action):
    if hasattr(action, '_short_action_id'):
        return action._short_action_id
    filepath = os.path.relpath(action.__code__.co_filename, hookenv.charm_dir())
    return "%s:%s:%s" % (filepath,
                         action.__code__.co_firstlineno,
                         action.__code__.co_name)
def kubernetes_token():
    try:
        account_file = os.path.join(
            charm_dir(), 'files', 'contrail-kubemanager-serviceaccount.yaml')
        check_output(["snap", "run", "kubectl", "apply", "-f", account_file])
    except Exception as e:
        log("Can't apply manifest for service account: {}".format(e))
        return None
    token_id = None
    for i in range(10):
        try:
            token_id = check_output([
                "snap", "run", "kubectl", "get", "sa", "contrail-kubemanager",
                "-n", "contrail",
                "-ogo-template=\"{{(index .secrets 0).name}}\""
            ]).decode('UTF-8').strip('\"')
        except Exception as e:
            log("Can't get SA for contrail-kubemanager {}".format(e))
            return None
        if token_id:
            break
        time.sleep(1)
    if not token_id:
        return None
    try:
        token_64 = check_output([
            "snap", "run", "kubectl", "get", "secret", token_id, "-n",
            "contrail", "-ogo-template=\"{{.data.token}}\""
        ]).decode('UTF-8').strip('\"')
        token = base64.b64decode(token_64).decode()
        return token
    except Exception as e:
        log("Can't get secret for token: {}".format(e))

    return None
Beispiel #53
0
 def register(cls, filepath):
     if filepath not in Handler._HANDLERS:
         _filepath = os.path.relpath(filepath, hookenv.charm_dir())
         if LOG_OPTS['register']:
             hookenv.log('Registering external reactive handler for %s' % _filepath, level=hookenv.DEBUG)
         Handler._HANDLERS[filepath] = cls(filepath)
     return Handler._HANDLERS[filepath]
Beispiel #54
0
def setup_ufw():
    """setup_ufw configures iptables to masquerade traffic for VPN clients.
    UFW is used for convenience; changes will persist across reboots."""
    config = hookenv.config()

    # Undo prior edits to ufw rules
    rules = check_output([
        'awk', '-f',
        os.path.join(hookenv.charm_dir(), 'reset-ufw-rules.awk'),
        '/etc/ufw/before.rules'
    ],
                         universal_newlines=True)
    with open('/etc/ufw/before.rules', 'w') as f:
        f.write(rules)

    iface, _ = resolve_iface()

    check_call([
        'sed', '-i', '-e',
        's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/',
        '/etc/default/ufw'
    ])
    check_call([
        'sed', '-i',
        r'1i# START OPENVPN RULES\n# NAT table rules\n*nat\n:POSTROUTING ACCEPT [0:0]\n# Allow traffic from OpenVPN client to network interface\n\n-A POSTROUTING -s %s -o %s -j MASQUERADE\nCOMMIT\n# END OPENVPN RULES\n'
        % (config.get('subnet'), iface), '/etc/ufw/before.rules'
    ])
    check_call(['ufw', 'allow', 'ssh'])
    check_call(['ufw', 'allow', '1194/udp'])
    check_call(['ufw', '--force', 'enable'])

    set_state('openvpn.ufw.ready')
Beispiel #55
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.")
Beispiel #56
0
def client_cert(source, destination, user=None, group=None):
    """
    Copy the client certificate to the destination creating directories if
    needed and assign ownership if set.

    :param string source: The path to look for the certificate, if None
    the certificate will be copied from the default location.
    :param string destination: The path to save the certificate.
    :param string user: The optional name of the user to own the certificate.
    :param string group: The optional name of the group to own certificate.
    """
    _ensure_directory(destination, user, group)

    if not source:
        # When source not specified use the default client certificate path.
        source = os.path.join(charm_dir(),
                              'easy-rsa/easyrsa3/pki/issued/client.crt')

    # Check for the client certificate.
    if os.path.isfile(source):
        # Copy the client certificate to the destination.
        copy2(source, destination)
    else:
        # No client certificate file, get the value from unit data.
        client_cert_key = 'tls.client.certificate'
        # Save the certificate data to the destination.
        _save_unitdata(client_cert_key, destination)

    chown(destination, user, group)

    # Set the destination path for the client certificate path on the unitdata.
    unitdata.kv().set('client-cert-path', destination)
Beispiel #57
0
def manage():
    manager = ServiceManager([
        {
            'service': 'cf-webadmin',
            'ports': [8070],  # ports to open after start
            'provided_data': [
                HttpRelation(port=8070)
            ],
            'required_data': [
                OrchestratorRelation(),
                MysqlRelation(),
                NatsRelation(),
                UAARelation(),
                CloudControllerDBRelation(),
                UAADBRelation(),
                {'charm_dir': hookenv.charm_dir()},
            ],
            'data_ready': [
                actions.setup_uaac_client,
                actions.render_webadmin_config,
                helpers.render_template(
                    source='upstart.conf',
                    target='/etc/init/cf-webadmin.conf'),
            ],
        },
    ])
    manager.manage()
Beispiel #58
0
    def update_rally_checkfiles(self):
        if not self.is_rally_enabled:
            return

        # Copy run_rally.sh to /usr/local/bin
        rally_script = os.path.join(hookenv.charm_dir(), 'files',
                                    'run_rally.py')
        host.rsync(rally_script, self.scripts_dir, options=['--executability'])

        ostestsfile = os.path.join('/home', self._rallyuser, 'ostests.txt')
        render(source='ostests.txt.j2',
               target=ostestsfile,
               context=self._get_rally_checks_context(),
               owner=self._rallyuser,
               group=self._rallyuser)

        proxy_settings = hookenv.env_proxy_settings()
        if proxy_settings:
            content = '\n'.join([
                '{}={}'.format(proxy_var, proxy_var_val)
                for proxy_var, proxy_var_val in proxy_settings.items()
            ])
        else:
            content = ''

        context = {
            'schedule': self.rally_cron_schedule,
            'user': self._rallyuser,
            'cmd': os.path.join(self.scripts_dir, 'run_rally.py'),
        }
        content += '\n#\n{schedule} {user} timeout -k 840s -s SIGTERM 780s {cmd}'.format(
            **context)
        with open(self.rally_cron_file, 'w') as fd:
            fd.write('# Juju generated - DO NOT EDIT\n{}\n\n'.format(content))
Beispiel #59
0
def add_implicit_package_signing_keys():
    # Rather than blindly add these keys, we should sniff
    # config['install_sources'] for apache.org or datastax.com urls and
    # add only the appropriate keys.
    for key in ('apache', 'datastax'):
        path = os.path.join(hookenv.charm_dir(), 'lib', '{}.key'.format(key))
        subprocess.check_call(['apt-key', 'add', path],
                              stdin=subprocess.DEVNULL)