Ejemplo n.º 1
0
def list_pools():
    """Return a list of all Ceph pools."""
    try:
        pool_list = check_output(['ceph', 'osd', 'pool', 'ls']).decode('UTF-8')
        return pool_list
    except CalledProcessError as e:
        action_fail(str(e))
Ejemplo n.º 2
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)})
Ejemplo n.º 3
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,
            })
Ejemplo n.º 4
0
def manual_backup():
    backend = Backend()
    # keyfile is in vault
    directories_to_backup = action_get('directory-list')
    timestamp = "{:%Y-%m-%d-%H-%M-%S}".format(datetime.datetime.now())
    try:
        log("Running a manual backup on {}".format(directories_to_backup),
            level=DEBUG)
        for directory in directories_to_backup:
            check_output(
                ["/snap/bin/preserve",
                 "--configdir",
                 os.path.join(os.path.expanduser("~"), ".config"),
                 "--loglevel", "error",
                 "create",
                 "{name}-{timestamp}".format(name=directory,
                                             timestamp=timestamp),
                 str(directory),
                 "--backend", backend.get_backend(),
                 "--vault"
                 ])
    except OSError as err:
        log("Create backup failed with error: {}".format(err.message),
            level=ERROR)
        action_fail("List backup failed with error: {}".format(err.message))
Ejemplo n.º 5
0
def restore_backup():
    backend = Backend()
    backup_name = action_get("backup-name")
    restore_path = action_get("restore-path")

    if not os.path.exists(restore_path):
        log("Creating restore path: {}".format(restore_path))
        os.mkdir(restore_path)
    try:
        log("Restoring backup {} to {}".format(backup_name, restore_path),
            level=DEBUG)
        check_output(
            ["/snap/bin/preserve",
             "--configdir",
             os.path.join(os.path.expanduser("~"), ".config"),
             "--loglevel", "error",
             "restore",
             "--backend", backend.get_backend(),
             "--vault",
             backup_name, restore_path])

    except OSError as err:
        log("Restore backup failed with error: {}".format(err.message),
            level=ERROR)
        action_fail("Restore backup failed with error: {}".format(err.message))
Ejemplo n.º 6
0
def configure_interface():
    """
    Configure an ethernet interface
    """
    iface_name = action_get('iface-name')
    cidr = action_get('cidr')

    # cidr is optional
    if cidr:
        try:
            # Add may fail, but change seems to add or update
            router.ip('address', 'change', cidr, 'dev', iface_name)
        except subprocess.CalledProcessError as e:
            action_fail('Command failed: %s (%s)' %
                        (' '.join(e.cmd), str(e.output)))
            return
        finally:
            remove_state('vpe.configure-interface')
            status_set('active', 'ready!')

    try:
        router.ip('link', 'set', 'dev', iface_name, 'up')
    except subprocess.CalledProcessError as e:
        action_fail('Command failed: %s (%s)' %
                    (' '.join(e.cmd), str(e.output)))
    finally:
        remove_state('vpe.configure-interface')
        status_set('active', 'ready!')
def create_pool():
    pool_name = action_get("name")
    pool_type = action_get("pool-type")
    try:
        if pool_type == "replicated":
            replicas = action_get("replicas")
            replicated_pool = ReplicatedPool(name=pool_name,
                                             service='admin',
                                             replicas=replicas)
            replicated_pool.create()

        elif pool_type == "erasure":
            crush_profile_name = action_get("erasure-profile-name")
            erasure_pool = ErasurePool(name=pool_name,
                                       erasure_code_profile=crush_profile_name,
                                       service='admin')
            erasure_pool.create()
        else:
            log("Unknown pool type of {}. Only erasure or replicated is "
                "allowed".format(pool_type))
            action_fail("Unknown pool type of {}. Only erasure or replicated "
                        "is allowed".format(pool_type))
    except CalledProcessError as e:
        action_fail("Pool creation failed because of a failed process. "
                    "Ret Code: {} Message: {}".format(e.returncode, e.message))
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")
Ejemplo n.º 9
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))
Ejemplo n.º 10
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)})
def pool_get():
    key = action_get("key")
    pool_name = action_get("pool_name")
    try:
        value = check_output(['ceph', 'osd', 'pool', 'get', pool_name, key])
        return value
    except CalledProcessError as e:
        action_fail(e.message)
Ejemplo n.º 12
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')
Ejemplo n.º 13
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')
Ejemplo n.º 14
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})
Ejemplo n.º 15
0
def copy_pool():
    try:
        source = hookenv.action_get("source")
        target = hookenv.action_get("target")
        subprocess.check_call([
            'rados', 'cppool',
            source, target
        ])
    except subprocess.CalledProcessError as e:
        hookenv.action_fail("Error copying pool: {}".format(str(e)))
Ejemplo n.º 16
0
def get_disk_stats():
    try:
        # https://www.kernel.org/doc/Documentation/iostats.txt
        with open('/proc/diskstats', 'r') as diskstats:
            return diskstats.readlines()
    except IOError as err:
        log('Could not open /proc/diskstats.  Error: {}'.format(err.message))
        action_fail('replace-osd failed because /proc/diskstats could not '
                    'be opened {}'.format(err.message))
        return None
Ejemplo n.º 17
0
def get_devices():
    """Parse 'devices' action parameter, returns list."""
    devices = []
    for path in hookenv.action_get('devices').split(' '):
        path = path.strip()
        if not os.path.isabs(path):
            hookenv.action_fail('{}: Not absolute path.'.format(path))
            raise
        devices.append(path)
    return devices
def delete_erasure_profile():
    name = action_get("name")

    try:
        remove_erasure_profile(service='admin', profile_name=name)
    except CalledProcessError as e:
        log("Remove erasure profile failed with error {}".format(e.message),
            level="ERROR")
        action_fail("Remove erasure profile failed with error: {}".format(
            e.message))
Ejemplo n.º 19
0
def generate_hmac_action(*args):
    """Generate an HMAC in the backend HSM"""
    # try and get the reactive relation instance for hsm:
    # We only do this because there's no @action(<name>) yet that we could
    # access from the reactive file.
    hsm = reactive.RelationBase.from_state('hsm.available')
    if hsm is None:
        hookenv.action_fail(
            "Can't generate an HMAC in associated HSM because HSM is not "
            "available.")
    barbican.generate_hmac(hsm)
Ejemplo n.º 20
0
def main(args):
    action_name = os.path.basename(args[0])
    try:
        action = ACTIONS[action_name]
    except KeyError:
        return "Action %s undefined" % action_name
    else:
        try:
            action(args)
        except Exception as e:
            action_fail(str(e))
Ejemplo n.º 21
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))
Ejemplo n.º 22
0
def not_ready_add():
    actions = [
        'vpe.add-corporation',
        'vpe.connect-domains',
        'vpe.delete-domain-connections',
        'vpe.remove-corporation',
    ]

    if helpers.any_states(*actions):
        action_fail('VPE is not configured')

    status_set('blocked', 'vpe is not configured')
Ejemplo n.º 23
0
def get_health():
    """
    Returns the output of 'ceph health'.

    On error, 'unknown' is returned.
    """
    try:
        value = check_output(['ceph', 'health']).decode('UTF-8')
        return value
    except CalledProcessError as e:
        action_fail(str(e))
        return 'Getting health failed, health unknown'
def list_pools():
    try:
        cluster = connect()
        pool_list = cluster.list_pools()
        cluster.shutdown()
        return pool_list
    except (rados.IOError,
            rados.ObjectNotFound,
            rados.NoData,
            rados.NoSpace,
            rados.PermissionError) as e:
        action_fail(e.message)
Ejemplo n.º 25
0
def generate_mkek_action(*args):
    """Generate an MKEK in the backend HSM"""
    # try and get the reactive relation instance for hsm:
    # We only do this because there's no @action(<name>) yet that we could
    # access from the reactive file.
    hsm = reactive.RelationBase.from_state('hsm.available')
    if hsm is None:
        hookenv.action_fail(
            "Can't generate an MKEK in associated HSM because HSM is not "
            "available.")
        return
    with charms_openstack.charm.provide_charm_instance as barbican_charm:
        barbican_charm.generate_mkek(hsm)
def main(args):
    action_name = os.path.basename(args[0])
    try:
        action = ACTIONS[action_name]
    except KeyError:
        s = "Action {} undefined".format(action_name)
        action_fail(s)
        return s
    else:
        try:
            action(args)
        except Exception as e:
            action_fail("Action {} failed: {}".format(action_name, str(e)))
Ejemplo n.º 27
0
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")
def remove_pool():
    try:
        pool_name = action_get("name")
        cluster = connect()
        log("Deleting pool: {}".format(pool_name))
        cluster.delete_pool(str(pool_name))  # Convert from unicode
        cluster.shutdown()
    except (rados.IOError,
            rados.ObjectNotFound,
            rados.NoData,
            rados.NoSpace,
            rados.PermissionError) as e:
        log(e)
        action_fail(e)
Ejemplo n.º 29
0
def main(argv):
    action_name = _get_action_name()
    actions_yaml_path = _get_actions_yaml_path()
    parser = get_action_parser(actions_yaml_path, action_name)
    args = parser.parse_args(argv)
    try:
        action = ACTIONS[action_name]
    except KeyError:
        return "Action %s undefined" % action_name
    else:
        try:
            action(args)
        except Exception as e:
            action_fail(str(e))
Ejemplo n.º 30
0
def remove_pool():
    try:
        pool_name = action_get("name")
        set_mon_allow_pool_delete(delete=True)
        subprocess.check_call([
            'ceph', 'osd', 'pool', 'delete',
            pool_name, pool_name,
            '--yes-i-really-really-mean-it',
        ])
    except subprocess.CalledProcessError as e:
        log(e)
        action_fail("Error deleting pool: {}".format(str(e)))
    finally:
        set_mon_allow_pool_delete(delete=False)
Ejemplo n.º 31
0
def touch():
    gitDirectory = 'openair-cn'
    cassandraServerIP = action_get('cassandra-server-ip')

    status_set('active', 'configure-cassandra: configuring Cassandra ...')

    err = ''
    try:
        filename = '/tmp/x0'
        cmd = [
            'echo "{cassandraServerIP}" >{filename}'.format(
                filename=filename, cassandraServerIP=cassandraServerIP)
        ]
        result, err = charms.sshproxy._run(cmd)
    except:
        action_fail('command failed:' + err)
    else:
        action_set({'outout': result})
    finally:
        clear_flag('actions.touch')
Ejemplo n.º 32
0
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))
Ejemplo n.º 33
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)
Ejemplo n.º 34
0
def pool_get():
    """
    Returns a key from a pool using 'ceph osd pool get'.

    The key is provided via the 'key' action parameter and the
    pool provided by the 'pool_name' parameter. These are used when
    running 'ceph osd pool get <pool_name> <key>', the result of
    which is returned.

    On failure, 'unknown' will be returned.
    """
    key = action_get("key")
    pool_name = action_get("pool_name")
    try:
        value = (check_output(['ceph', 'osd', 'pool', 'get', pool_name,
                               key]).decode('UTF-8'))
        return value
    except CalledProcessError as e:
        action_fail(str(e))
        return 'unknown'
Ejemplo n.º 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)
                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))
    })
Ejemplo n.º 36
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")
Ejemplo n.º 37
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
Ejemplo n.º 38
0
def curl_call(action_name, path, method, headers={}, data=""):
    try:
        import requests
        resp = None
        curl_url = "http://{}:{}{}".format(rest_ip, rest_port, path)
        request_method = getattr(requests, method.lower())
        resp = request_method(curl_url,
                              headers=headers,
                              data=data,
                              verify=False)
        result = resp.text
    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        action_fail(
            "command failed: {}, endpoint: {}:{}, filename: {}, line: {}".
            format(e, rest_ip, rest_port, fname, exc_tb.tb_lineno))
    else:
        action_set({"stdout": result, "errors": e})
    finally:
        remove_flag(action_name)
Ejemplo n.º 39
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')
Ejemplo n.º 40
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')
Ejemplo n.º 41
0
def set_quota():
    max_files = action_get('max-files')
    max_bytes = action_get('max-bytes')
    directory = action_get('directory')

    if not os.path.exists(directory):
        action_fail("Directory must exist before setting quota")
    attr = "ceph.quota.{}"
    value = None
    if max_files:
        attr.format("max_files")
        value = str(max_files)
    elif max_bytes:
        attr.format("max_bytes")
        value = str(max_bytes)

    try:
        xattr.setxattr(directory, attr, value)
    except IOError as err:
        action_fail("Unable to set xattr on {}.  Error: {}".format(
            directory, err))
Ejemplo n.º 42
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)
Ejemplo n.º 43
0
def main(args):
    action_name = os.path.basename(args[0])
    try:
        action = ACTIONS[action_name]
    except KeyError:
        return "Action %s undefined" % action_name
    else:
        try:
            action(args)
        except vault.VaultError as e:
            hookenv.action_fail(str(e))
        except Exception:
            exc = format_exc()
            hookenv.log(exc, hookenv.ERROR)
            hookenv.action_fail(exc.splitlines()[-1])
        else:
            # we were successful, so commit changes from the action
            unitdata.kv().flush()
            # try running handlers based on new state
            try:
                charms.reactive.main()
            except Exception:
                exc = format_exc()
                hookenv.log(exc, hookenv.ERROR)
                hookenv.action_fail(exc.splitlines()[-1])
Ejemplo n.º 44
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')
Ejemplo n.º 45
0
def main(argv):
    action = os.path.basename(argv[0])
    try:
        params = hookenv.action_get()

        if action == "maintenance-mode-start":
            maintenance_mode_start(params)
        elif action == "maintenance-mode-stop":
            maintenance_mode_stop(params)
        elif hookenv.leader_get("maintenance_mode") is not None:
            hookenv.action_fail("Application is in maintenance mode")
            return

        if action == "replication-pause":
            replication_pause(params)
        elif action == "replication-resume":
            replication_resume(params)
        elif action == "wal-e-backup":
            wal_e_backup(params)
        elif action == "wal-e-list-backups":
            wal_e_list_backups(params)
        elif action == "wal-e-restore":
            reactive_action("action.wal-e-restore")
        elif action == "switchover":
            reactive_action("action.switchover")
        elif action in ("maintenance-mode-start", "maintenance-mode-stop"):
            reactive_action("action.{}".format(action))  # Sets status, exits.
        else:
            hookenv.action_fail("Action {} not implemented".format(action))
    except Exception:
        hookenv.action_fail("Unhandled exception")
        tb = traceback.format_exc()
        hookenv.action_set(dict(traceback=tb))
        hookenv.log("Unhandled exception in action {}".format(action))
        print(tb)
Ejemplo n.º 46
0
def make_cache_tier():
    backer_pool = action_get("backer-pool")
    cache_pool = action_get("cache-pool")
    cache_mode = action_get("cache-mode")

    # Pre flight checks
    if not pool_exists('admin', backer_pool):
        log("Please create {} pool before calling create-cache-tier".format(
            backer_pool))
        action_fail("create-cache-tier failed. Backer pool {} must exist "
                    "before calling this".format(backer_pool))

    if not pool_exists('admin', cache_pool):
        log("Please create {} pool before calling create-cache-tier".format(
            cache_pool))
        action_fail("create-cache-tier failed. Cache pool {} must exist "
                    "before calling this".format(cache_pool))

    pool = Pool(service='admin', name=backer_pool)
    try:
        pool.add_cache_tier(cache_pool=cache_pool, mode=cache_mode)
    except CalledProcessError as err:
        log("Add cache tier failed with message: {}".format(err.message))
        action_fail("create-cache-tier failed.  Add cache tier failed with "
                    "message: {}".format(err.message))
Ejemplo n.º 47
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')
Ejemplo n.º 48
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')
Ejemplo n.º 49
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')
Ejemplo n.º 50
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')
Ejemplo n.º 51
0
def upload_signed_csr(*args):
    if not hookenv.is_leader():
        hookenv.action_fail('Please run action on lead unit')
        return

    action_config = hookenv.action_get()
    root_ca = action_config.get('root-ca')
    if root_ca:
        hookenv.leader_set(
            {'root-ca': base64.b64decode(root_ca).decode("utf-8")})
    vault_pki.upload_signed_csr(
        base64.b64decode(action_config['pem']).decode("utf-8"),
        allowed_domains=action_config.get('allowed-domains'),
        allow_subdomains=action_config.get('allow-subdomains'),
        enforce_hostnames=action_config.get('enforce-hostnames'),
        allow_any_name=action_config.get('allow-any-name'),
        max_ttl=action_config.get('max-ttl'))
    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')
Ejemplo n.º 52
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')
Ejemplo n.º 53
0
def restart(args):
    """Restart services.

    :param args: Unused
    :type args: List[str]
    """
    deferred_only = action_get("deferred-only")
    services = action_get("services").split()
    # Check input
    if deferred_only and services:
        action_fail("Cannot set deferred-only and services")
        return
    if not (deferred_only or services):
        action_fail("Please specify deferred-only or services")
        return
    if action_get('run-hooks'):
        _run_deferred_hooks()
    if deferred_only:
        os_utils.restart_services_action(deferred_only=True)
    else:
        os_utils.restart_services_action(services=services)
    assess_status(register_configs())
Ejemplo n.º 54
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')
Ejemplo n.º 55
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})
Ejemplo n.º 56
0
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')
Ejemplo n.º 57
0
def restart_services(args):
    """Restart services.

    :param args: Unused
    :type args: List[str]
    """
    deferred_only = hookenv.action_get("deferred-only")
    services = hookenv.action_get("services").split()
    # Check input
    if deferred_only and services:
        hookenv.action_fail("Cannot set deferred-only and services")
        return
    if not (deferred_only or services):
        hookenv.action_fail("Please specify deferred-only or services")
        return
    if hookenv.action_get('run-hooks'):
        _run_deferred_hooks()
    if deferred_only:
        os_utils.restart_services_action(deferred_only=True)
    else:
        os_utils.restart_services_action(services=services)
    with charms_openstack.charm.provide_charm_instance() as charm_instance:
        charm_instance._assess_status()
Ejemplo n.º 58
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})
Ejemplo n.º 59
0
def action_run_command():
    """Execute the run command via action."""
    try:
        if in_action_context():
            cmd = action_get('command')
            output, err = run_command(cmd)
            if len(err):
                action_fail("Command '{}' returned error code {}".format(
                    cmd, err))
            else:
                if isinstance(output, bytes):
                    action_set({'output': output[:100000]})
                elif isinstance(output, str):
                    action_set(
                        {'output': textwrap.shorten(output, width=100000)})
                else:
                    action_set({'output': output})
    except subprocess.CalledProcessError as e:
        if in_action_context():
            action_fail('Command failed: %s (%s)' %
                        (' '.join(e.cmd), str(e.output)))
    finally:
        clear_flag('actions.run')
Ejemplo n.º 60
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)})