コード例 #1
0
ファイル: actions.py プロジェクト: cplane-networks/dvnd-juju
def ogr_zone_detail(args):
    aggr_name = action_get('aggregate-name')

    cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-details {}'"\
          .format(aggr_name)
    res = commands.getoutput(cmd)
    action_set({'result-map.message': res})
コード例 #2
0
def remove_services():
    load_config_file(os.path.join(os.path.sep, "etc", "cinder", "cinder.conf"))

    host = action_get(key="host")
    services = model_query({}, models.Service, read_deleted="no",
                           session=get_session())

    if host not in ("unused", "",):
        services = services.filter(models.Service.host == host)
    else:
        ands = []
        for service in DEFAULT_SERVICES:
            ands.append(and_(models.Service.host != service))
        services = services.filter(*ands)

    removed_services = []
    ctxt = context.get_admin_context()

    for service in services.all():
        log("Removing service:%d, hostname:%s" % (service.id, service.host))
        try:
            if os_release("cinder") >= "liberty":
                cinder_manage_remove(service.binary, service.host)
            else:
                db.service_destroy(ctxt, service.id)
        except:
            action_set({'traceback': traceback.format_exc()})
            action_fail("Cannot remove service: %s" % service.host)
        else:
            removed_services.append(service.host)

    action_set({'removed': ",".join(removed_services)})
コード例 #3
0
def remove_services(args):
    host = action_get(key="host")
    services = cinder_manage_service_list()

    if host not in ("unused", "",):
        services = [s for s in services if s.host == host]
    else:
        services = [s for s in services if s.host not in DEFAULT_SERVICES]

    removed_services = []

    for service in services:
        log("Removing binary:{}, hostname:{}"
            .format(service.binary, service.host))
        try:
            if CompareOpenStackReleases(os_release("cinder")) >= "liberty":
                cinder_manage_remove(service.binary, service.host)
            else:
                action_fail("Cannot remove service: {}".format(service.host))
        except:
            action_set({'traceback': traceback.format_exc()})
            action_fail("Cannot remove service: {}".format(service.host))
        else:
            removed_services.append(service.host)

    action_set({'removed': ",".join(removed_services)})
コード例 #4
0
def add_user():
    """Add a swauth user to swift."""
    if config('auth-type') == 'swauth':
        try_initialize_swauth()
        account = action_get('account')
        username = action_get('username')
        password = action_get('password')
        bind_port = config('bind-port')
        bind_port = determine_api_port(bind_port, singlenode_mode=True)
        success = True
        try:
            check_call([
                "swauth-add-user",
                "-A", "http://localhost:{}/auth/".format(bind_port),
                "-K", leader_get('swauth-admin-key'),
                "-a", account, username, password])
        except CalledProcessError as e:
            success = False
            log("Has a problem adding user: {}".format(e.output))
            action_fail(
                "Adding user {} failed with: \"{}\""
                .format(username, str(e)))
        if success:
            message = "Successfully added the user {}".format(username)
            action_set({
                'add-user.result': 'Success',
                'add-user.message': message,
            })
コード例 #5
0
def backup():
    basedir = (action_get("basedir")).lower()
    compress = (action_get("compress"))
    incremental = (action_get("incremental"))
    sstpw = config("sst-password")
    optionlist = []

    # innobackupex will not create recursive dirs that do not already exist,
    # so help it along
    if not os.path.exists(basedir):
        os.makedirs(basedir)

    # Build a list of options to pass to innobackupex
    if compress is "true":
        optionlist.append("--compress")

    if incremental is "true":
        optionlist.append("--incremental")

    try:
        subprocess.check_call(
            ['innobackupex', '--compact', '--galera-info', '--rsync',
             basedir, '--user=sstuser', '--password='******'time-completed': (strftime("%Y-%m-%d %H:%M:%S", gmtime())),
            'outcome': 'Success'}
        )
    except subprocess.CalledProcessError as e:
        action_set({
            'time-completed': (strftime("%Y-%m-%d %H:%M:%S", gmtime())),
            'output': e.output,
            'return-code': e.returncode,
            'traceback': traceback.format_exc()})
        action_fail("innobackupex failed, you should log on to the unit"
                    "and check the status of the database")
コード例 #6
0
ファイル: actions.py プロジェクト: cplane-networks/dvnd-juju
def create_ogr_zone(args):
    aggr_name = action_get('aggregate-name')
    avail_zone = action_get('avail-zone')
    ogr_compute = action_get('ogr-compute')

    cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-create {} {}'"\
          .format(aggr_name, avail_zone)
    commands.getoutput(cmd)
    cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-add-host {} {}'"\
          .format(aggr_name, ogr_compute)
    commands.getoutput(cmd)
    if config("openstack-version") == "liberty" or \
       config("openstack-version") == "mitaka":
        cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-details {}'"\
              .format(aggr_name)
    else:
        cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-show {}'"\
              .format(aggr_name)
    res = commands.getoutput(cmd)
    action_set({'result-map.message': res})
    relation_info = {
        'aggr-name': aggr_name
    }
    if config("openstack-version") == "pike" or \
       config("openstack-version") == "ocata":
        for rid in relation_ids('neutron-api-cplane'):
            for unit in related_units(rid):
                relation_set(relation_id=rid, relation_settings=relation_info)
コード例 #7
0
def list_backups():
    backend = Backend()
    try:
        log("Listing backups", level=DEBUG)
        preserve_list = check_output(
            ["/snap/bin/preserve",
             "--configdir",
             os.path.join(os.path.expanduser("~"), ".config"),
             "--loglevel", "error",
             "list",
             "--vault",
             "--backend", backend.get_backend(),
             "--json"])
        try:
            backup_list = json.loads(preserve_list)
            action_set({"message": backup_list})
        except ValueError as verr:
            log("Unable to load preserve output as json. Error {}".format(
                verr), level=ERROR)
            action_fail(
                "Json loading of preserve output failed: {}".format(verr))

    except OSError as err:
        log("List backup failed with error: {}".format(err.message),
            level=ERROR)
        action_fail("List backup failed with error: {}".format(err.message))
コード例 #8
0
ファイル: actions.py プロジェクト: cplane-networks/dvnd-juju
def add_ogr_vm(args):
    name = action_get('name')
    image_path = download_ogr_image()

    cmd = "su - ubuntu -c 'source nova.rc && glance image-create --name {} \
--visibility public --container-format bare --disk-format qcow2 < {}'"\
          .format(name, image_path)
    res = commands.getoutput(cmd)
    action_set({'result-map.message': res})
コード例 #9
0
def traceroute():
    try:
        result, err = _run('traceroute -m {} {}'.format(action_get('hops'), action_get('destination')))
    except:
        action_fail('traceroute command failed')
    else:
        # Here you can send results back from ping, if you had time to parse it
        action_set({'output': result})
    finally:
        remove_flag('actions.traceroute')
コード例 #10
0
def nmap():
    err = ''
    try:
        result, err = _run('nmap {}'.format(action_get('destination')))
    except:
        action_fail('nmap command failed:' + err)
    else:
        action_set({'outout': result})
    finally:
        remove_flag('actions.nmap')
コード例 #11
0
def pingme_forreal():
    try:
        result, err = run('ping -qc {} {}'.format(action_get('count'), action_get('destination')))
    except:
        action_fail('ping command failed')
    finally:
        remove_flag('actions.ping')

    # Here you can send results back from ping, if you had time to parse it
    action_set({'output': result})
コード例 #12
0
ファイル: actions.py プロジェクト: cplane-networks/dvnd-juju
def create_network(args):
    net_name = action_get('net-name')
    net_type = action_get('net-type')
    phys_net = action_get('phys-net')

    cmd = "su - ubuntu -c 'source nova.rc && neutron net-create {} \
--provider:network_type={} --provider:physical_network={}'"\
          .format(net_name, net_type, phys_net)
    res = commands.getoutput(cmd)
    action_set({'result-map.message': res})
コード例 #13
0
ファイル: actions.py プロジェクト: cplane-networks/dvnd-juju
def delete_ogr_zone(args):
    aggr_name = action_get('aggregate-name')
    ogr_compute = action_get('ogr-compute')

    cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-remove-host {} {}\
'".format(aggr_name, ogr_compute)
    res = commands.getoutput(cmd)
    cmd = "su - ubuntu -c 'source nova.rc && nova aggregate-delete {}'"\
          .format(aggr_name)
    res = commands.getoutput(cmd)
    action_set({'result-map.message': res})
コード例 #14
0
    def set_data(value):
        """
        Set the key:value to be passed to ``action_set``

        :param list value: A hash containing the key and value
        """
        try:
            action_set(value)
            return True
        except OSError:
            return False
コード例 #15
0
ファイル: tempest.py プロジェクト: openstack/charm-tempest
 def run_test(self, tox_target):
     """Run smoke tests"""
     action_args = hookenv.action_get()
     branch_name = action_args['branch']
     git_dir, logfile, run_dir = self.get_tempest_files(branch_name)
     self.setup_directories()
     self.setup_git(branch_name, git_dir)
     self.execute_tox(run_dir, logfile, tox_target)
     action_info = self.parse_tempest_log(logfile)
     action_info['tempest-logfile'] = logfile
     hookenv.action_set(action_info)
コード例 #16
0
ファイル: tempest.py プロジェクト: jhobbs/charm-tempest
 def run_test(self, tox_target):
     """Run smoke tests"""
     action_args = hookenv.action_get()
     branch_name = action_args['branch']
     git_dir, logfile, run_dir = self.get_tempest_files(branch_name)
     action_info = {
         'tempest-logfile': logfile,
     }
     self.setup_git(branch_name, git_dir)
     self.execute_tox(run_dir, logfile, tox_target)
     hookenv.action_set(action_info)
コード例 #17
0
ファイル: actions.py プロジェクト: cplane-networks/dvnd-juju
def create_subnet(args):
    sub_name = action_get('sub-name')
    net_name = action_get('net-name')
    cidr = action_get('cidr')
    pool_start = action_get('pool-start')
    pool_end = action_get('pool-end')

    cmd = "su - ubuntu -c 'source nova.rc && neutron subnet-create --name {} \
{} {} --no-gateway --allocation-pool start={},end={}'"\
          .format(sub_name, net_name, cidr, pool_start, pool_end)
    res = commands.getoutput(cmd)
    action_set({'result-map.message': res})
コード例 #18
0
def _rename_volume_host(currenthost, newhost):
    services = cinder_manage_service_list()
    services = [s for s in services if s.host == currenthost]
    if services:
        try:
            cinder_manage_volume_update_host(currenthost, newhost)
        except:
            action_set({'traceback': traceback.format_exc()})
            action_fail("Cannot update host {}".format(currenthost))
    else:
        action_fail("Cannot update host attribute from {}, {} not found"
                    .format(currenthost, currenthost))
コード例 #19
0
ファイル: parseBenchmark.py プロジェクト: apache/bigtop
def parse_benchmark_output():
    """
    Parse the output from the benchmark and set the action results:
    """
    results = {}

    # Find all of the interesting things
    regex = re.compile('\t+(.*)=(.*)')
    for line in sys.stdin.readlines():
        m = regex.match(line)
        if m:
            results[m.group(1)] = m.group(2)
    hookenv.action_set({"meta.raw": json.dumps(results)})
コード例 #20
0
def run_test():
    action_config = action_get()
    priv_key_file = "/home/ubuntu/.ssh/id_rsa"
    base_cmd = "bundle exec inspec exec"
    test_cmd = base_cmd + " {} -t ssh://hiotest@{} --key-files={}".format(
        action_config["test-name"], action_config["target-ip"], priv_key_file
    )
    try:
        output = subprocess.check_output(test_cmd.split(), stderr=subprocess.STDOUT, cwd="/srv/hardening/ssh/")
        returncode = 0
    except subprocess.CalledProcessError as ex:
        output = ex.output
        returncode = ex.returncode
    action_set({"test-output": output.decode("utf-8")})
コード例 #21
0
ファイル: ping.py プロジェクト: mjs/juju
def main():
    targets = hookenv.action_get('targets')
    hookenv.log("Got: {}".format(targets))
    # Undo the formatting passed into the action so juju didn't puke
    targets = targets.replace('=', ':')
    targets = targets.replace('(', '{')
    targets = targets.replace(')', '}')
    hookenv.log('Parsed to: {}'.format(targets))
    targets = json.loads(targets)
    results = {}
    # Get unit names from targets dict and ping their public address
    for target, ip in targets.items():
        results[target] = ping_check(ip)
    action_set({'results': results})
コード例 #22
0
ファイル: actions.py プロジェクト: gnuoy/charm-hacluster
def status(args):
    """Display status of cluster resources.
    Includes inactive resources in results."""
    cmd = ['crm', 'status', '--inactive']

    try:
        result = subprocess.check_output(cmd).decode('utf-8')
        action_set({'result': result})
    except subprocess.CalledProcessError as e:
        log("ERROR: Failed call to crm resource status. "
            "output: {}. return-code: {}".format(e.output, e.returncode))
        log(traceback.format_exc())
        action_set({'result': ''})
        action_fail("failed to get cluster status")
コード例 #23
0
def tidydefaults(args):
    """Delete default zone and zonegroup metadata"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not deleting defaults')
        return
    try:
        multisite.tidy_defaults()
        action_set(
            values={
                'message': 'default zone and zonegroup deleted'
            }
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable delete default zone and zonegroup'
                    ': {}'.format(zone, cpe.output))
コード例 #24
0
ファイル: git_reinstall.py プロジェクト: BillTheBest/hyper-c
def git_reinstall():
    """Reinstall from source and restart services.

    If the openstack-origin-git config option was used to install openstack
    from source git repositories, then this action can be used to reinstall
    from updated git repositories, followed by a restart of services."""
    if not git_install_requested():
        action_fail('openstack-origin-git is not configured')
        return

    try:
        git_install(config('openstack-origin-git'))
        config_changed()
    except:
        action_set({'traceback': traceback.format_exc()})
        action_fail('git-reinstall resulted in an unexpected error')
コード例 #25
0
def promote(args):
    """Promote zone associated with local RGW units to master/default"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not promoting')
        return
    try:
        multisite.modify_zone(zone,
                              default=True, master=True)
        multisite.update_period()
        action_set(
            values={'message': 'zone:{} promoted to '
                    'master/default'.format(zone)}
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable to promote zone:{} '
                    'to master: {}'.format(zone, cpe.output))
コード例 #26
0
def readwrite(args):
    """Mark zone associated with local RGW units as read write"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not marking read write')
        return
    try:
        multisite.modify_zone(zone, readonly=False)
        multisite.update_period()
        action_set(
            values={
                'message': 'zone:{} marked as read write'.format(zone)
            }
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable mark zone:{} '
                    'as read write: {}'.format(zone, cpe.output))
コード例 #27
0
ファイル: zap_disk.py プロジェクト: openstack/charm-ceph-osd
def zap():
    if not hookenv.action_get('i-really-mean-it'):
        hookenv.action_fail('i-really-mean-it is a required parameter')
        return

    failed_devices = []
    not_block_devices = []
    devices = get_devices()
    for device in devices:
        if not is_block_device(device):
            not_block_devices.append(device)
        if (is_device_mounted(device) or
                is_active_bluestore_device(device) or
                is_mapped_luks_device(device)):
            failed_devices.append(device)

    if failed_devices or not_block_devices:
        message = ""
        if failed_devices:
            message = "{} devices are mounted: {}".format(
                len(failed_devices),
                ", ".join(failed_devices))
        if not_block_devices:
            if message is not '':
                message += "\n\n"
            message += "{} devices are not block devices: {}".format(
                len(not_block_devices),
                ", ".join(not_block_devices))
        hookenv.action_fail(message)
        return
    db = kv()
    used_devices = db.get('osd-devices', [])
    for device in devices:
        zap_disk(device)
        if device in used_devices:
            used_devices.remove(device)
    db.set('osd-devices', used_devices)
    db.flush()
    hookenv.action_set({
        'message': "{} disk(s) have been zapped, to use them as OSDs, run: \n"
                   "juju run-action {} add-disk osd-devices=\"{}\"".format(
                       len(devices),
                       hookenv.local_unit(),
                       " ".join(devices))
    })
コード例 #28
0
ファイル: remove_device.py プロジェクト: freyes/ubuntu-lxd
def remove_devices():
    container = action_get(key="container")
    device_type = action_get(key="device.type")
    device_name = action_get(key="device.name")

    removed_devices = []
    for name, device in filter_devices_by_type(container, device_type):
        if name == device_name or 'parent' in device.keys() \
           and (device["parent"] == device_name or
                device["parent"] == "br-%s" % device_name):
            try:
                remove_device(container, name)
            except:
                action_set({'traceback': traceback.format_exc()})
                action_fail('Cannot remove device: %s from: %s' % (name,
                                                                   container))
            else:
                removed_devices.append(device_name)

    action_set({'removed': ",".join(removed_devices)})
コード例 #29
0
ファイル: actions.py プロジェクト: gnuoy/charm-hacluster
def cleanup(args):
    """Cleanup an/all hacluster resource(s).
        Optional arg "resource=res_xyz_abc" """
    resource_name = (action_get("resource")).lower()
    if resource_name == 'all':
        cmd = ['crm_resource', '-C']
    else:
        cmd = ['crm', 'resource', 'cleanup', resource_name]

    try:
        subprocess.check_call(cmd)
        action_set({'result': 'success'})
    except subprocess.CalledProcessError as e:
        log("ERROR: Failed call to crm resource cleanup for {}. "
            "output: {}. return-code: {}".format(resource_name, e.output,
                                                 e.returncode))
        log(traceback.format_exc())
        action_set({'result': 'failure'})
        action_fail("failed to cleanup crm resource "
                    "'{}'".format(resource_name))
コード例 #30
0
ファイル: actions.py プロジェクト: msmarcal/charm-swift-proxy
def diskusage(args):
    """Runs 'swift-recon -d' and returns values in GB.
    @raises CalledProcessError on check_output failure
    @raises Exception on any other failure
    """
    try:
        raw_output = check_output(['swift-recon', '-d']).decode('UTF-8')
        recon_result = list(line.strip().split(' ')
                            for line in raw_output.splitlines()
                            if 'Disk' in line)
        for line in recon_result:
            if 'space' in line:
                line[4] = str(int(line[4]) // (1024 * 1024 * 1024)) + 'GB'
                line[6] = str(int(line[6]) // (1024 * 1024 * 1024)) + 'GB'
        result = [' '.join(x) for x in recon_result]
        action_set({'output': result})
    except CalledProcessError as e:
        action_set({'output': e.output})
        action_fail('Failed to run swift-recon -d')
    except:
        raise
コード例 #31
0
def action_upgrade():
    state = ''
    status = ''
    try:
        state, status = vnf_upgrade()
    except Exception as e:
        # If any exception happens within the action execution, we'll capture
        # it and report it via `action_fail`. Normal errors within the
        # execution of your operational logic should be caught, the state
        # should be set to STATE_FAIL and returned with a meaningful status.
        action_fail('Primitive failed: {} ({})'.format(e))
    else:
        # Send the state and a status message to the operator.
        action_set({'state': state, 'status': status})

        # If we're in a FAIL state, call action_fail to maintain compatibility
        # with charms not specific to OSM.
        if state == charms.osm.STATE_FAIL:
            action_fail('Primitive failed.')
    finally:
        clear_flag('actions.upgrade')
コード例 #32
0
def sshcmd():
    '''
    Create and Activate the network corporation
    '''
    commands = action_get('commands').split("\\n")
    # multi line is accepted with \n to separate then converted because juju does not allow advanced types like list or json :(
    cmdsMultiLines = """
    {}
    """.format("\n".join(commands))

    status_set('maintenance', 'running cmd on fortios')
    try:
        log("trying to run cmd: %s on fortios" % cmdsMultiLines)
        stdout, stderr = fortios.sshcmd(cmdsMultiLines)
    except Exception as e:
        action_fail('cmd on fortios failed reason:' + repr(e))
    else:
        log('sshcmd resp %s' % stdout)
        action_set({'output': stdout})
    remove_state('actions.sshcmd')
    status_set('active', 'alive')
コード例 #33
0
def diskusage(args):
    """Runs 'swift-recon -d' and returns values in GB.
    @raises CalledProcessError on check_output failure
    @raises Exception on any other failure
    """
    try:
        raw_output = check_output(['swift-recon', '-d']).decode('UTF-8')
        recon_result = list(line.strip().split(' ')
                            for line in raw_output.splitlines()
                            if 'Disk' in line)
        for line in recon_result:
            if 'space' in line:
                line[4] = str(int(line[4]) // (1024 * 1024 * 1024)) + 'GB'
                line[6] = str(int(line[6]) // (1024 * 1024 * 1024)) + 'GB'
        result = [' '.join(x) for x in recon_result]
        action_set({'output': result})
    except CalledProcessError as e:
        action_set({'output': e.output})
        action_fail('Failed to run swift-recon -d')
    except:
        raise
コード例 #34
0
def replication_resume(params):
    if not postgresql.is_secondary():
        hookenv.action_fail("Not a hot standby")
        return

    con = postgresql.connect()
    con.autocommit = True

    offset = postgresql.wal_received_offset(con)
    hookenv.action_set(dict(offset=offset))

    cur = con.cursor()
    if postgresql.has_version("10"):
        cur.execute("SELECT pg_is_wal_replay_paused()")
    else:
        cur.execute("SELECT pg_is_xlog_replay_paused()")
    if cur.fetchone()[0] is False:
        # Not a failure, per lp:1670613
        hookenv.action_set(dict(result="Already resumed"))
        return
    if postgresql.has_version("10"):
        cur.execute("SELECT pg_wal_replay_resume()")
    else:
        cur.execute("SELECT pg_xlog_replay_resume()")
    hookenv.action_set(dict(result="Resumed"))
コード例 #35
0
def zap():
    if not hookenv.action_get('i-really-mean-it'):
        hookenv.action_fail('i-really-mean-it is a required parameter')
        return

    failed_devices = []
    not_block_devices = []
    devices = get_devices()
    for device in devices:
        if not is_block_device(device):
            not_block_devices.append(device)
        if is_device_mounted(device) or is_active_bluestore_device(device):
            failed_devices.append(device)

    if failed_devices or not_block_devices:
        message = ""
        if failed_devices:
            message = "{} devices are mounted: {}".format(
                len(failed_devices), ", ".join(failed_devices))
        if not_block_devices:
            if message is not '':
                message += "\n\n"
            message += "{} devices are not block devices: {}".format(
                len(not_block_devices), ", ".join(not_block_devices))
        hookenv.action_fail(message)
        return
    db = kv()
    used_devices = db.get('osd-devices', [])
    for device in devices:
        zap_disk(device)
        if device in used_devices:
            used_devices.remove(device)
    db.set('osd-devices', used_devices)
    db.flush()
    hookenv.action_set({
        'message':
        "{} disk(s) have been zapped, to use them as OSDs, run: \n"
        "juju run-action {} add-disk osd-devices=\"{}\"".format(
            len(devices), hookenv.local_unit(), " ".join(devices))
    })
コード例 #36
0
def user_create():
    user = action_get('name')
    groups = action_get('groups') or ''
    protect_resources(user)

    users = user_list()
    if user in list(users):
        action_fail('User "{}" already exists.'.format(user))
        return

    # Create the secret
    # TODO: make the token format less magical so it doesn't get out of
    # sync with the function that creates secrets in k8s-master.py.
    token = '{}::{}'.format(user, layer.kubernetes_master.token_generator())
    layer.kubernetes_master.create_secret(token, user, user, groups)

    # Create a kubeconfig
    ca_crt = layer.kubernetes_common.ca_crt_path
    kubeconfig_path = '/home/ubuntu/{}-kubeconfig'.format(user)
    public_address, public_port = layer.kubernetes_master.get_api_endpoint()
    public_server = 'https://{0}:{1}'.format(public_address, public_port)

    layer.kubernetes_common.create_kubeconfig(kubeconfig_path,
                                              public_server,
                                              ca_crt,
                                              token=token,
                                              user=user)
    os.chmod(kubeconfig_path, 0o644)

    # Tell the people what they've won
    fetch_cmd = 'juju scp {}:{} .'.format(hookenv.local_unit(),
                                          kubeconfig_path)
    action_set({'msg': 'User "{}" created.'.format(user)})
    action_set({'users': ', '.join(list(users) + [user])})
    action_set({'kubeconfig': fetch_cmd})
コード例 #37
0
def purge_deb_files():
    probe_package_command = 'dpkg --list etcd'
    return_code = call(split(probe_package_command))
    if return_code != 0:
        # The return code from dpkg --list when the package is
        # non existant
        action_set({'dpkg.list.message': 'dpkg probe return_code > 0',
                    'skip.package.purge': 'True'})
        return
    log('Purging deb configuration files post migration', 'INFO')
    cmd = 'apt-get purge -y etcd'
    try:
        check_call(split(cmd))
    except CalledProcessError as cpe:
        action_fail({'apt.purge.message': cpe.message})

    for f in deb_paths['config']:
        try:
            log('Removing file {}'.format(f), 'INFO')
            os.remove(f)
        except FileNotFoundError:
            k = 'purge.missing.{}'.format(os.path.basename(f))
            msg = 'Did not purge {}. File not found.'.format(f)
            action_set({k: msg})
        except:
            k = 'purge.error.{}'.format(f)
            msg = 'Failed to purge {}. Manual removal required.'.format(k)
            action_set({k: msg})
コード例 #38
0
def bootstrap_pxc(args):
    """ Force a bootstrap on this node

    This action will run bootstrap-pxc on this node bootstrapping the cluster.
    This action should only be run after a cold start requiring a bootstrap.
    This action should only be run on the node with the highest sequence number
    as displayed in workgoup status and found in grastate.dat.
    If this unit has the highest sequence number and is not the juju leader
    node, a subsequent action run of notify-bootstrapped is required.
    """

    try:
        # Force safe to bootstrap
        percona_utils.set_grastate_safe_to_bootstrap()
        # Boostrap this node
        percona_utils.bootstrap_pxc()
        percona_utils.notify_bootstrapped()
    except (percona_utils.GRAStateFileNotFound, OSError) as e:
        action_set({'output': e.output, 'return-code': e.returncode})
        action_fail("The GRAState file does not exist or cannot "
                    "be written to.")
    except (subprocess.CalledProcessError, Exception) as e:
        action_set({
            'output': e.output,
            'return-code': e.returncode,
            'traceback': traceback.format_exc()
        })
        action_fail("The bootstrap-pxc failed. "
                    "See traceback in show-action-output")
    action_set({
        'output':
        "Bootstrap succeeded. "
        "Wait for the other units to run update-status"
    })
    percona_utils.assess_status(percona_utils.register_configs())
コード例 #39
0
def start_transcoder():
    stream_ip = action_get('stream-ip')
    output_port = action_get('output-port')

    err = ''
    try:
        cmd = "sudo rm /etc/systemd/system/opencv.service >/dev/null 2>&1; "
        cmd += "sudo systemctl stop opencv.service >/dev/null 2>&1; "
        cmd += "sudo systemctl daemon-reload"
        result, err = charms.sshproxy._run(cmd)
    except:
        action_fail('command failed: ' + err)
        remove_state('actions.start-transcoder')
        return

    err = ''
    try:
        cmd = "echo '[Unit]' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'Description=OpenCV' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo '' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo '[Service]' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'Type=simple' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'User=ubuntu' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'WorkingDirectory=/home/ubuntu' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'ExecStart=/usr/bin/python live_server.py {0} {1}' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && ".format(
            stream_ip, output_port)
        cmd += "echo 'Restart=always' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'RestartSec=5' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo '' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo '[Install]' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "echo 'WantedBy=multi-user.target' | sudo tee -a /etc/systemd/system/opencv.service > /dev/null && "
        cmd += "sudo systemctl daemon-reload && "
        cmd += "sudo systemctl start opencv.service"
        result, err = charms.sshproxy._run(cmd)
    except:
        action_fail('command failed: ' + err)
    else:
        action_set({'output': result, 'errors': err})
    finally:
        remove_state('actions.start-transcoder')
コード例 #40
0
def list_unconsumed_queues(args):
    """List queues which are unconsumed in RabbitMQ"""
    log("Listing unconsumed queues...", level=INFO)
    count = 0
    for vhost in list_vhosts():
        try:
            queue_info_dict = vhost_queue_info(vhost)
        except CalledProcessError as e:
            # if no queues, just raises an exception
            action_set({'output': e.output, 'return-code': e.returncode})
            action_fail("Failed to query RabbitMQ vhost {} queues"
                        "".format(vhost))
            return False

        for queue in queue_info_dict:
            if queue['consumers'] == 0:
                vhostqueue = ''
                value = ''
                try:
                    vhostqueue = "unconsumed-queues.{}".format(count)
                    value = OrderedDict((
                        ('vhost', vhost),
                        ('name', queue['name']),
                        ('messages', queue['messages']),
                    ))
                    action_set({vhostqueue: json.dumps(value)})
                except Exception as e:
                    log('{}, vhostqueue={}, value={}'.format(
                        e, vhostqueue, value),
                        level=ERROR)
                count += 1

    log("{} unconsumed queue(s) found".format(count), level=INFO)
    action_set({'unconsumed-queue-count': count})
コード例 #41
0
def check_queues(args):
    """Check for queues with greater than N messages.
    Return those queues to the user."""
    queue_depth = (action_get('queue-depth'))
    vhost = (action_get('vhost'))
    # rabbitmqctl's output contains lines we don't want, such as
    # 'Listing queues ..' and '...done.', which may vary by release.
    # Actual queue results *should* always look like 'test\t0'
    queue_pattern = re.compile(r"^(.*)\t([0-9]+$)")
    try:
        queue_lines = check_output(
            ['rabbitmqctl', 'list_queues', '-q', '-p',
             vhost]).decode('utf-8').splitlines()
        filtered = filter(
            None,  # filter out empty records
            map(lambda line: queue_pattern.findall(line), queue_lines))
        queues = [(queue, int(size)) for [[queue, size]] in filtered]
        result = {queue: size for queue, size in queues if size >= queue_depth}
        action_set({'output': result, 'outcome': 'Success'})
    except CalledProcessError as e:
        action_set({'output': e.output})
        action_fail('Failed to run rabbitmqctl list_queues')
コード例 #42
0
def set_server():
    try:
        # Get the target service info
        target_ip = action_get('server-ip')
        target_port = action_get('server-port')

        data = '{{"ip" : "{}", "port" : {} }}'. \
               format(target_ip, target_port)

        cmd = format_curl(
            'POST',
            '/server',
            data,
        )

        result, err = charms.sshproxy._run(cmd)
    except Exception as e:
        action_fail('command failed: {}, errors: {}'.format(e, e.output))
    else:
        action_set({'stdout': result, 'errors': err})
    finally:
        remove_flag('actions.set-server')
コード例 #43
0
def action_set_policy():
    """Set the policy for a given user.

    Sets the policy (bw and qos) for the specified user_id
    """
    err = ''
    updated = False
    try:
        user_id = action_get('user_id')
        bw = action_get('bw')
        qos = action_get('qos')

        # If this were a functional vnf, you would perform your operation here
        # and may return a value to indicate success or failure.
        updated = True

    except Exception as err:
        action_fail(str(err))
    else:
        action_set({'updated': updated})
    finally:
        clear_flag('actions.set-policy')
コード例 #44
0
def hugepages_report():
    '''Action to return current hugepage usage and kernel cmdline for static
    hugepage allocation. Takes no params.
    '''
    outmap = {}
    try:
        devp = "{}/devices/system/node/node*/hugepages/*/*".format(SYSFS)
        outmap['hugepagestats'] = subprocess.check_output(
            "grep -H . {}".format(devp),
            shell=True).decode('UTF-8')
    except subprocess.CalledProcessError as e:
        hookenv.log(e)
        hookenv.action_fail(
            "Getting hugepages report failed: {}".format(e.message)
        )
    with open(KERNELCMD, 'rb') as cmdline:
        try:
            outmap['kernelcmd'] = cmdline.read().strip()
        except IOError as e:
            hookenv.action_fail('Could not read {}: {}'.format(KERNELCMD, e))
            return
    hookenv.action_set(outmap)
コード例 #45
0
def backup(args):
    basedir = (action_get("basedir")).lower()
    compress = action_get("compress")
    incremental = action_get("incremental")
    sstpw = _get_password("sst-password")
    optionlist = []

    # innobackupex will not create recursive dirs that do not already exist,
    # so help it along
    if not os.path.exists(basedir):
        os.makedirs(basedir)

    # Build a list of options to pass to innobackupex
    if compress:
        optionlist.append("--compress")

    if incremental:
        optionlist.append("--incremental")

    # xtrabackup 2.4 (introduced in Bionic) doesn't support compact backups
    if CompareHostReleases(lsb_release()['DISTRIB_CODENAME']) < 'bionic':
        optionlist.append("--compact")

    try:
        subprocess.check_call(
            ['innobackupex', '--galera-info', '--rsync', basedir,
             '--user=sstuser', '--password={}'.format(sstpw)] + optionlist)
        action_set({
            'time-completed': (strftime("%Y-%m-%d %H:%M:%S", gmtime())),
            'outcome': 'Success'}
        )
    except subprocess.CalledProcessError as e:
        action_set({
            'time-completed': (strftime("%Y-%m-%d %H:%M:%S", gmtime())),
            'output': e.output,
            'return-code': e.returncode,
            'traceback': traceback.format_exc()})
        action_fail("innobackupex failed, you should log on to the unit"
                    "and check the status of the database")
コード例 #46
0
def touch():
    err = ''
    try:
        filename = action_get('filename')
        cmd = ['touch {}'.format(filename)]
        result, err = charms.sshproxy._run(cmd)
        cmd = ['sudo sysctl -w net.ipv4.ip_forward=1']
        result, err = charms.sshproxy._run(cmd)
        cmd = ['sudo sysctl -w net.ipv4.conf.all.proxy_arp=1']
        result, err = charms.sshproxy._run(cmd)
        cmd = ['sudo ip link set ens4 up']
        result, err = charms.sshproxy._run(cmd)
        cmd = ['sudo ip link set ens5 up']
        result, err = charms.sshproxy._run(cmd)
        cmd = ['sudo netplan apply']
        result, err = charms.sshproxy._run(cmd)
    except:
        action_fail('command failed:' + err)
    else:
        action_set({'outout': result})
    finally:
        clear_flag('actions.touch')
コード例 #47
0
def generate_root_ca(*args):
    if not hookenv.is_leader():
        hookenv.action_fail('Please run action on lead unit')
        return

    action_config = hookenv.action_get()
    root_ca = vault_pki.generate_root_ca(
        ttl=action_config['ttl'],
        allow_any_name=action_config['allow-any-name'],
        allowed_domains=action_config['allowed-domains'],
        allow_bare_domains=action_config['allow-bare-domains'],
        allow_subdomains=action_config['allow-subdomains'],
        allow_glob_domains=action_config['allow-glob-domains'],
        enforce_hostnames=action_config['enforce-hostnames'],
        max_ttl=action_config['max-ttl'])
    hookenv.leader_set({'root-ca': root_ca})
    hookenv.action_set({'output': root_ca})
    set_flag('charm.vault.ca.ready')
    set_flag('pki.backend.tuned')
    # reissue any certificates we might previously have provided
    set_flag('certificates.reissue.requested')
    set_flag('certificates.reissue.global.requested')
コード例 #48
0
def conf_port():
    """
    Configure an ethernet interface
    """
    port = action_get('port')
    ip = action_get('ip')
    mtu = action_get('mtu')
    netmask = action_get('netmask')
    if mtu:
        params = {
            "name": port,
            "mode": "static",
            "ip": ip + " " + netmask,
            "allowaccess": "ping",
            "mtu-override": "enable",
            "mtu": mtu
        }
    else:
        params = {
            "name": port,
            "mode": "static",
            "ip": ip + " " + netmask,
            "allowaccess": "ping",
            "vdom": "root"
        }
    status_set('maintenance', 'running cmd on fortios')
    try:
        is_set, resp = fortios.set("system", "interface", data=params)
    except Exception as e:
        action_fail('API call on fortios failed reason:' + repr(e))
    else:
        if is_set is True:
            log('API call successfull response %s' % resp)
            action_set({'output': resp})
        else:
            action_fail('API call on fortios failed reason:' + resp)
    remove_state('actions.conf-port')
    status_set('active', 'alive')
コード例 #49
0
ファイル: ns.py プロジェクト: davigar15/layer-ns
def action_add_user():
    """Add a user to the database."""
    err = ''
    output = ''
    try:
        username = action_get('username')
        bw = action_get('bw')
        qos = action_get('qos')
        tariff = action_get('tariff')

        # Get the configuration, which should contain the juju username and
        # password. The endpoint and model will be discovered automatically
        cfg = config()

        client = charms.osm.ns.NetworkService(
            user=cfg['juju-username'],
            secret=cfg['juju-password'],
        )

        user_id = add_user(client, username, tariff)
        if user_id > 0:
            success = set_policy(client, user_id, bw, qos)
        else:
            log("user_id is 0; add_user failed.")

        log("Output from charm: {}".format(output))

    except Exception as err:
        log(str(err))
        log(str(traceback.format_exc()))
        action_fail(str(err))
    else:
        action_set({
            'user-id': user_id,
            'policy-set': success,
        })
    finally:
        clear_flag('actions.add-user')
コード例 #50
0
def get_sp_metadata(*args):
    if not os.path.exists(SP_METADATA_FILE):
        return hookenv.action_fail(
            "The SP metadata file {} does not exist".format(SP_METADATA_FILE))
    sp_metadata = ""
    # By stripping double new lines and tabs we get human readable xml
    # Otherwise, show-action-status is a garbled mess
    with open(SP_METADATA_FILE, 'rt') as f:
        for line in f.readlines():
            line = line.replace("\t", "  ")
            if line.strip(" ") == "\n":
                continue
            sp_metadata += line
    return hookenv.action_set({"output": sp_metadata})
コード例 #51
0
def add_user(args):
    options = action_get()
    password = options.get('password', None)
    if not password:
        password = pwgen(16)
    hashed = bcrypt.hashpw(password.encode('utf-8'),
                           bcrypt.gensalt()).decode('utf-8')
    opts = {
        'password': hashed,
        'log': True,
        'awayMessage': '',
        'networks': [],
        'sessions': [],
        'clientSettings': {}
    }
    path = '/etc/thelounge/users/{}.json'.format(options['user'])
    with open(path, 'w+') as f:
        f.write(json.dumps(opts, indent=4))
    chownr(path, 'thelounge', 'thelounge')
    action_set({
        'password': password,
        'user': options['user'],
    })
コード例 #52
0
def backup():
    basedir = (action_get("basedir")).lower()
    compress = (action_get("compress"))
    incremental = (action_get("incremental"))
    sstpw = config("sst-password")
    optionlist = []

    # innobackupex will not create recursive dirs that do not already exist,
    # so help it along
    if not os.path.exists(basedir):
        os.makedirs(basedir)

    # Build a list of options to pass to innobackupex
    if compress is "true":
        optionlist.append("--compress")

    if incremental is "true":
        optionlist.append("--incremental")

    try:
        subprocess.check_call([
            'innobackupex', '--compact', '--galera-info', '--rsync', basedir,
            '--user=sstuser', '--password='******'time-completed': (strftime("%Y-%m-%d %H:%M:%S", gmtime())),
            'outcome': 'Success'
        })
    except subprocess.CalledProcessError as e:
        action_set({
            'time-completed': (strftime("%Y-%m-%d %H:%M:%S", gmtime())),
            'output': e.output,
            'return-code': e.returncode,
            'traceback': traceback.format_exc()
        })
        action_fail("innobackupex failed, you should log on to the unit"
                    "and check the status of the database")
コード例 #53
0
def remove_services():
    load_config_file(os.path.join(os.path.sep, "etc", "cinder", "cinder.conf"))

    host = action_get(key="host")
    services = model_query({},
                           models.Service,
                           read_deleted="no",
                           session=get_session())

    if host not in (
            "unused",
            "",
    ):
        services = services.filter(models.Service.host == host)
    else:
        ands = []
        for service in DEFAULT_SERVICES:
            ands.append(and_(models.Service.host != service))
        services = services.filter(*ands)

    removed_services = []
    ctxt = context.get_admin_context()

    for service in services.all():
        log("Removing service:%d, hostname:%s" % (service.id, service.host))
        try:
            if os_release("cinder") >= "liberty":
                cinder_manage_remove(service.binary, service.host)
            else:
                db.service_destroy(ctxt, service.id)
        except:
            action_set({'traceback': traceback.format_exc()})
            action_fail("Cannot remove service: %s" % service.host)
        else:
            removed_services.append(service.host)

    action_set({'removed': ",".join(removed_services)})
コード例 #54
0
def apply_manifest():
    """
    Applies a user defined manifest with kubectl
    """
    _, apply_path = tempfile.mkstemp(suffix=".json")
    try:
        manifest = json.loads(action_get("json"))
        with open(apply_path, "w") as manifest_file:
            json.dump(manifest, manifest_file)
        output = _kubectl(["apply", "-f", apply_path])

        action_set({
            "summary": "Manifest applied.",
            "output": output.decode("utf-8"),
        })
    except subprocess.CalledProcessError as e:
        action_fail("kubectl failed with exit code {} and message: {}".format(
            e.returncode, e.output))
    except json.JSONDecodeError as e:
        action_fail("Failed to parse JSON manifest: {}".format(str(e)))
    except Exception as e:
        action_fail("Failed to apply manifest: {}".format(str(e)))
    finally:
        os.unlink(apply_path)
コード例 #55
0
def generate_cert(*args):
    """Generates a certificate and sets it in the action output.

    The certificate parameters are provided via the action parameters from
    the user. If the current unit is not the leader or the vault calls fail,
    this will result in a failed command.
    """

    if not hookenv.is_leader():
        hookenv.action_fail('Please run action on lead unit')
        return

    action_config = hookenv.action_get()
    sans_list = action_config.get('sans')
    try:
        new_crt = vault_pki.generate_certificate(
            cert_type='server',
            common_name=action_config.get('common-name'),
            sans=list(sans_list.split()),
            ttl=action_config.get('ttl'),
            max_ttl=action_config.get('max-ttl'))
        hookenv.action_set({'output': new_crt})
    except vault.VaultError as e:
        hookenv.action_fail(str(e))
コード例 #56
0
def check_queues(args):
    """Check for queues with greater than N messages.
    Return those queues to the user."""
    queue_depth = (action_get('queue-depth'))
    vhost = (action_get('vhost'))
    result = []
    # rabbitmqctl's output contains lines we don't want, such as
    # 'Listing queues ..' and '...done.', which may vary by release.
    # Actual queue results *should* always look like 'test\t0'
    queue_pattern = re.compile('.*\t[0-9]*')
    try:
        queues = check_output(['rabbitmqctl', 'list_queues', '-p',
                               vhost]).decode('utf-8').split('\n')
        result = list({
            queue: size
            for (queue, size) in
            [i.split('\t') for i in queues if re.search(queue_pattern, i)]
            if int(size) >= queue_depth
        })

        action_set({'output': result, 'outcome': 'Success'})
    except CalledProcessError as e:
        action_set({'output': e.output})
        action_fail('Failed to run rabbitmqctl list_queues')
コード例 #57
0
def switchover_action():
    try:
        params = hookenv.action_get()
        anointed = params["master"]
        master = get_master()

        if not master:
            hookenv.action_fail("There is no master. Cannot switchover")
            return

        if not anointed:
            hookenv.action_fail("anointed master was not specified")
            return

        if master == anointed:
            hookenv.action_set(
                dict(result="{} is already master"
                     "".format(anointed)))
            return

        peer_rel = helpers.get_peer_relation()
        if anointed != hookenv.local_unit() and anointed not in peer_rel:
            hookenv.action_fail("Invalid unit name {}".format(anointed))
            return

        leader_set(anointed_master=anointed)
        update_replication_states()

        switchover_status()

        hookenv.action_set(
            dict(result="Initiated switchover of master to {}"
                 "".format(anointed)))

    finally:
        reactive.remove_state("action.switchover")
コード例 #58
0
ファイル: layer_netutils.py プロジェクト: TCSOSM-20/devops
def dig():
    err = ''
    try:
        nsserver = action_get('nsserver')
        host = action_get('host')
        nstype = action_get('type')
        cmd = "dig"

        if nsserver:
            cmd += " @{}".format(nsserver)
        if host:
            cmd += " {}".format(host)
        else:
            action_fail('Hostname required.')
        if nstype:
            cmd += " -t {}".format(nstype)

        result, err = charms.sshproxy._run(cmd)
    except:
        action_fail('dig command failed:' + err)
    else:
        action_set({'outout': result})
    finally:
        remove_flag('actions.dig')
コード例 #59
0
ファイル: actions.py プロジェクト: dshcherb/charm-ceilometer
def ceilometer_upgrade(args):
    """Run ceilometer-upgrade

    @raises Exception if the ceilometer-upgrade fails.
    """
    try:
        ceilometer_upgrade_helper(register_configs())
        action_set({'outcome': 'success, ceilometer-upgrade completed.'})
    except FailedAction as e:
        if e.outcome:
            action_set({'outcome': e.outcome})
        if e.trace:
            action_set({'traceback': e.trace})
        raise Exception(str(e.message))
コード例 #60
0
def user_create():
    user = action_get("name")
    groups = action_get("groups") or ""
    protect_resources(user)

    users = user_list()
    if user in list(users):
        action_fail('User "{}" already exists.'.format(user))
        return

    # Validate the name
    if re.search("[^0-9A-Za-z:@.-]+", user):
        msg = "User name may only contain alphanumeric characters, ':', '@', '-' or '.'"
        action_fail(msg)
        return

    # Create the secret
    # TODO: make the token format less magical so it doesn't get out of
    # sync with the function that creates secrets in kubernetes_control_plane.py.
    token = "{}::{}".format(user,
                            layer.kubernetes_control_plane.token_generator())
    if not layer.kubernetes_control_plane.create_secret(
            token, user, user, groups):
        action_fail("Failed to create secret for: {}".format(user))
        return

    # Create a kubeconfig
    ca_crt = layer.kubernetes_common.ca_crt_path
    kubeconfig_path = "/home/ubuntu/{}-kubeconfig".format(user)
    endpoints = layer.kubernetes_control_plane.get_external_api_endpoints()
    if not endpoints:
        action_fail("Kubernetes client endpoints currently unavailable.")
        return
    public_server = layer.kubernetes_control_plane.get_api_urls(endpoints)[0]

    layer.kubernetes_common.create_kubeconfig(kubeconfig_path,
                                              public_server,
                                              ca_crt,
                                              token=token,
                                              user=user)
    os.chmod(kubeconfig_path, 0o644)

    # Tell the people what they've won
    fetch_cmd = "juju scp {}:{} .".format(hookenv.local_unit(),
                                          kubeconfig_path)
    action_set({"msg": 'User "{}" created.'.format(user)})
    action_set({"users": ", ".join(list(users) + [user])})
    action_set({"kubeconfig": fetch_cmd})