Beispiel #1
0
def get_info(host, *, users=None, connection=None):
    log.debug("Getting info about '{}'".format(host))

    user, host = connection.ssh_user, connection.ssh_host
    data = OrderedDict()
    data["ssh_user"] = user
    data["ssh_host"] = host
    data["ssh"] = "{}@{}".format(user, host)
    data["whoami"] = ssh_cmd(connection, "whoami")
    data["uname"] = ssh_cmd(connection, "uname")
    data["arch"] = ssh_cmd(connection, "uname -m")
    data["os_release"] = os_release(ssh_cmd(connection, "cat /etc/os-release"))
    data["agent_location"] = ssh_cmd(connection, "which cf-agent")
    data["policy_server"] = ssh_cmd(connection, "cat /var/cfengine/policy_server.dat")
    agent_version = ssh_cmd(connection, "cf-agent --version")
    if agent_version:
        # 'CFEngine Core 3.12.1 \n CFEngine Enterprise 3.12.1'
        #                ^ split and use this part for version number
        agent_version = agent_version.split()[2]
    data["agent_version"] = agent_version
    data["bin"] = {}
    for bin in ["dpkg", "rpm", "yum", "apt", "pkg"]:
        path = ssh_cmd(connection, "which {}".format(bin))
        if path:
            data["bin"][bin] = path

    log.debug("JSON data from host info: \n" + pretty(data))
    return data
Beispiel #2
0
def validate_args(args):
    if args.version is True:  # --version with no second argument
        print_version_info()
        exit_success()

    if args.version and args.command not in ["install", "packages"]:
        user_error("Cannot specify version number in '{}' command".format(
            args.command))

    if "hosts" in args and args.hosts:
        log.debug("validate_args, hosts in args, args.hosts='{}'".format(
            args.hosts))
        args.hosts = resolve_hosts(args.hosts)
    if "clients" in args and args.clients:
        args.clients = resolve_hosts(args.clients)
    if "bootstrap" in args and args.bootstrap:
        args.bootstrap = [
            strip_user(host_info)
            for host_info in resolve_hosts(args.bootstrap, private_ips=True)
        ]
    if "hub" in args and args.hub:
        args.hub = resolve_hosts(args.hub)

    if not args.command:
        user_error("Invalid or missing command")
    args.command = args.command.strip()
    validate_command(args.command, args)
Beispiel #3
0
def get_info(host, *, users=None, connection=None):
    log.debug("Getting info about '{}'".format(host))

    user, host = connection.ssh_user, connection.ssh_host
    data = OrderedDict()
    data["ssh_user"] = user
    data["ssh_host"] = host
    data["ssh"] = "{}@{}".format(user, host)
    data["whoami"] = ssh_cmd(connection, "whoami")
    data["uname"] = ssh_cmd(connection, "uname")
    data["arch"] = ssh_cmd(connection, "uname -m")
    data["os_release"] = os_release(ssh_cmd(connection, "cat /etc/os-release"))
    data["agent_location"] = ssh_cmd(connection, "which cf-agent")
    data["policy_server"] = ssh_cmd(connection,
                                    "cat /var/cfengine/policy_server.dat")
    agent_version = ssh_cmd(connection, "cf-agent --version")
    if agent_version:
        # 'CFEngine Core 3.12.1 \n CFEngine Enterprise 3.12.1'
        #                ^ split and use this part for version number
        agent_version = agent_version.split()[2]
    data["agent_version"] = agent_version
    data["bin"] = {}
    for bin in ["dpkg", "rpm", "yum", "apt", "pkg"]:
        path = ssh_cmd(connection, "which {}".format(bin))
        if path:
            data["bin"][bin] = path

    log.debug("JSON data from host info: \n" + pretty(data))
    return data
Beispiel #4
0
def connect(host, users=None):
    log.debug("Connecting to '{}'".format(host))
    if "@" in host:
        parts = host.split("@")
        assert len(parts) == 2
        host = parts[1]
        if not users:
            users = [parts[0]]
    if not users:
        users = [
            "Administrator", "ubuntu", "ec2-user", "centos", "vagrant", "root"
        ]
        # Similar to ssh, try own username first,
        # some systems will lock us out if we have too many failed attempts.
        if whoami() not in users:
            users = [whoami()] + users
    for user in users:
        try:
            log.debug("Attempting ssh: {}@{}".format(user, host))
            c = fabric.Connection(host=host, user=user)
            c.ssh_user = user
            c.ssh_host = host
            c.run("whoami", hide=True)
            return c
        except AuthenticationException:
            continue
    sys.exit("Could not ssh into '{}'".format(host))
Beispiel #5
0
def agent_run(host, *, connection=None):
    print("Triggering an agent run on: '{}'".format(host))
    command = "/var/cfengine/bin/cf-agent -Kf update.cf"
    output = ssh_sudo(connection, command)
    log.debug(output)
    command = "/var/cfengine/bin/cf-agent -K"
    output = ssh_sudo(connection, command)
    log.debug(output)
Beispiel #6
0
def agent_run(host, *, connection=None):
    print("Triggering an agent run on: '{}'".format(host))
    command = "/var/cfengine/bin/cf-agent -Kf update.cf"
    output = ssh_sudo(connection, command)
    log.debug(output)
    command = "/var/cfengine/bin/cf-agent -K"
    output = ssh_sudo(connection, command)
    log.debug(output)
Beispiel #7
0
def ssh_sudo(connection, cmd):
    try:
        log.debug("Running(sudo) over SSH: '{}'".format(cmd))
        result = connection.sudo(cmd, hide=True)
        output = result.stdout.strip()
        log.debug("'{}' -> '{}'".format(cmd, output))
        return output
    except UnexpectedExit:
        return None
Beispiel #8
0
def agent_run(host):
    print("Triggering an agent run on: '{}'".format(host))
    with remote.connect(host) as connection:
        command = "/var/cfengine/bin/cf-agent -Kf update.cf"
        output = remote.ssh_sudo(connection, command)
        log.debug(output)
        command = "/var/cfengine/bin/cf-agent -K"
        output = remote.ssh_sudo(connection, command)
        log.debug(output)
Beispiel #9
0
def disable_password_dialog(host):
    print("Disabling password change on hub: '{}'".format(host))
    api = "https://{}/api/user/admin".format(host)
    d = json.dumps({"password": "******"})
    creds = "admin:admin"
    c = "curl -X POST  -k {} -u {}  -H 'Content-Type: application/json' -d '{}'".format(
        api, creds, d)
    log.debug(c)
    os.system(c)
Beispiel #10
0
def install(hubs,
            clients,
            *,
            bootstrap=None,
            package=None,
            hub_package=None,
            client_package=None,
            version=None,
            demo=False,
            call_collect=False,
            edition=None):
    assert hubs or clients
    assert not (hubs and clients and package)
    # These assertions are checked in main.py

    if not hub_package:
        hub_package = package
    if not client_package:
        client_package = package
    if bootstrap:
        if type(bootstrap) is str:
            bootstrap = [bootstrap]
        save_file(os.path.join(cf_remote_dir(), "policy_server.dat"),
                  "\n".join(bootstrap + [""]))
    errors = 0
    if hubs:
        if type(hubs) is str:
            hubs = [hubs]
        for index, hub in enumerate(hubs):
            log.debug("Installing {} hub package on '{}'".format(edition, hub))
            errors += install_host(
                hub,
                hub=True,
                package=hub_package,
                bootstrap=bootstrap[index %
                                    len(bootstrap)] if bootstrap else None,
                version=version,
                demo=demo,
                call_collect=call_collect,
                edition=edition)
    for index, host in enumerate(clients or []):
        log.debug("Installing {} client package on '{}'".format(edition, host))
        errors += install_host(
            host,
            hub=False,
            package=client_package,
            bootstrap=bootstrap[index % len(bootstrap)] if bootstrap else None,
            version=version,
            demo=demo,
            edition=edition)
    if demo and hubs:
        for hub in hubs:
            print(
                "Your demo hub is ready: https://{}/ (Username: admin, Password: password)"
                .format(strip_user(hub)))
    return errors
Beispiel #11
0
def info(hosts, users=None):
    assert hosts
    log.debug("hosts='{}'".format(hosts))
    errors = 0
    for host in hosts:
        data = get_info(host, users=users)
        if data:
            print_info(data)
        else:
            errors += 1
    return errors
Beispiel #12
0
def agent_run(data, *, connection=None):
    host = data["ssh_host"]
    agent = data["agent"]
    print("Triggering an agent run on: '{}'".format(host))
    command = "{} -Kf update.cf".format(agent)
    ssh_func = ssh_cmd if data["os"] == "windows" else ssh_sudo
    output = ssh_func(connection, command)
    log.debug(output)
    command = "{} -K".format(agent)
    output = ssh_func(connection, command)
    log.debug(output)
Beispiel #13
0
def get_json(url):
    r = requests.get(url)
    assert r.status_code >= 200 and r.status_code < 300
    data = r.json()

    filename = os.path.basename(url)
    dir = cf_remote_dir("json")
    path = os.path.join(dir, filename)
    log.debug("Saving '{}' to '{}'".format(url, path))
    write_json(path, data)

    return data
Beispiel #14
0
def get_json(url):
    r = requests.get(url)
    assert r.status_code >= 200 and r.status_code < 300
    data = r.json()

    filename = os.path.basename(url)
    dir = cf_remote_dir("json")
    path = os.path.join(dir, filename)
    log.debug("Saving '{}' to '{}'".format(url, path))
    write_json(path, data)

    return data
Beispiel #15
0
 def find(self, tags, extension=None):
     if not self.extended_data:
         self.init_download()
     log.debug("Looking for tags: {}".format(tags))
     artifacts = self.artifacts
     if extension:
         artifacts = [a for a in self.artifacts if a.extension == extension]
     for tag in tags or []:
         tag = canonify(tag)
         artifacts = [a for a in artifacts if tag in a.tags]
         # Have to force evaluation using list comprehension,
         # since we are overwriting artifacts
     return artifacts
Beispiel #16
0
 def find(self, tags, extension=None):
     if not self.extended_data:
         self.init_download()
     log.debug("Looking for tags: {}".format(tags))
     artifacts = self.artifacts
     if extension:
         artifacts = [a for a in self.artifacts if a.extension == extension]
     for tag in tags or []:
         tag = canonify(tag)
         artifacts = [a for a in artifacts if tag in a.tags]
         # Have to force evaluation using list comprehension,
         # since we are overwriting artifacts
     return artifacts
Beispiel #17
0
def install(
        hubs,
        clients,
        *,
        bootstrap=None,
        package=None,
        hub_package=None,
        client_package=None,
        version=None,
        demo=False,
        call_collect=False):
    assert hubs or clients
    assert not (hubs and clients and package)
    # These assertions are checked in main.py

    if not hub_package:
        hub_package = package
    if not client_package:
        client_package = package
    if bootstrap:
        if type(bootstrap) is str:
            bootstrap = [bootstrap]
        save_file(os.path.join(cf_remote_dir(), "policy_server.dat"), "\n".join(bootstrap + [""]))
    if hubs:
        if type(hubs) is str:
            hubs = [hubs]
        for index, hub in enumerate(hubs):
            log.debug("Installing hub package on '{}'".format(hub))
            install_host(
                hub,
                hub=True,
                package=hub_package,
                bootstrap=bootstrap[index % len(bootstrap)] if bootstrap else None,
                version=version,
                demo=demo,
                call_collect=call_collect)
    for index, host in enumerate(clients or []):
        log.debug("Installing client package on '{}'".format(host))
        install_host(
            host,
            hub=False,
            package=client_package,
            bootstrap=bootstrap[index % len(bootstrap)] if bootstrap else None,
            version=version,
            demo=demo)
    if demo and hubs:
        for hub in hubs:
            print(
                "Your demo hub is ready: https://{}/ (Username: admin, Password: password)".
                format(strip_user(hub)))
Beispiel #18
0
def os_release(inp):
    if not inp:
        log.debug("Cannot parse os-release file (empty)")
        return None
    d = OrderedDict()
    for line in inp.splitlines():
        line = line.strip()
        if "=" not in line:
            continue
        key, sep, value = line.partition("=")
        assert "=" not in key
        if len(value) > 1 and value[0] == value[-1] and value[0] in ["'", '"']:
            value = value[1:-1]
        d[key] = value
    return d
Beispiel #19
0
def get_cloud_hosts(name, private_ips=False):
    if not os.path.exists(paths.CLOUD_STATE_FPATH):
        return []

    state = read_json(paths.CLOUD_STATE_FPATH)
    group_name = None
    hosts = []
    if name.startswith("@") and name in state:
        # @some_group given and exists
        group_name = name
    elif ("@" + name) in state:
        # group_name given and @group_name exists
        group_name = "@" + name

    if group_name is not None:
        for name, info in state[group_name].items():
            if name == "meta":
                continue
            log.debug("found name '{}' in state, info='{}'".format(name, info))
            hosts.append(info)
    else:
        if name in state:
            # host_name given and exists at the top level
            hosts.append(state[name])
        else:
            for group_name in [
                    key for key in state.keys() if key.startswith("@")
            ]:
                if name in state[group_name]:
                    hosts.append(state[group_name][name])

    ret = []
    for host in hosts:
        if private_ips:
            key = "private_ips"
        else:
            key = "public_ips"

        ips = host.get(key, [])
        if len(ips) > 0:
            if host.get("user"):
                ret.append('{}@{}'.format(host.get("user"), ips[0]))
            else:
                ret.append(ips[0])
        else:
            ret.append(None)

    return ret
Beispiel #20
0
def get_info(host, *, users=None, connection=None):
    log.debug("Getting info about '{}'".format(host))

    user, host = connection.ssh_user, connection.ssh_host
    data = OrderedDict()
    data["ssh_user"] = user
    data["ssh_host"] = host
    data["ssh"] = "{}@{}".format(user, host)
    data["whoami"] = ssh_cmd(connection, "whoami")
    systeminfo = ssh_cmd(connection, "systeminfo")
    if systeminfo:
        data["os"] = "windows"
        data["systeminfo"] = parse_systeminfo(systeminfo)
        data["package_tags"] = ["x86_64", "msi"]
        data["arch"] = "x86_64"
        agent = r'& "C:\Program Files\Cfengine\bin\cf-agent.exe"'
        data["agent"] = agent
        data["agent_version"] = parse_version(
            ssh_cmd(connection, '{} -V'.format(agent)))
    else:
        data["os"] = "unix"
        data["uname"] = ssh_cmd(connection, "uname")
        data["arch"] = ssh_cmd(connection, "uname -m")
        data["os_release"] = os_release(
            ssh_cmd(connection, "cat /etc/os-release"))
        data["agent_location"] = ssh_cmd(connection, "which cf-agent")
        data["policy_server"] = ssh_cmd(connection,
                                        "cat /var/cfengine/policy_server.dat")

        agent = r'/var/cfengine/bin/cf-agent'
        data["agent"] = agent
        data["agent_version"] = parse_version(
            ssh_cmd(connection, "{} --version".format(agent)))

        data["bin"] = {}
        for bin in ["dpkg", "rpm", "yum", "apt", "pkg"]:
            path = ssh_cmd(connection, "which {}".format(bin))
            if path:
                data["bin"][bin] = path

    log.debug("JSON data from host info: \n" + pretty(data))
    return data
Beispiel #21
0
def connect(host, users=None):
    log.debug("Connecting to '{}'".format(host))
    if "@" in host:
        parts = host.split("@")
        assert len(parts) == 2
        host = parts[1]
        if not users:
            users = [parts[0]]
    if not users:
        users = ["ubuntu", "ec2-user", "centos", "vagrant", "root"]
    for user in users:
        try:
            c = fabric.Connection(host=host, user=user)
            c.ssh_user = user
            c.ssh_host = host
            c.run("whoami", hide=True)
            return c
        except AuthenticationException:
            continue
    sys.exit("Could not ssh into '{}'".format(host))
Beispiel #22
0
def install(hub,
            clients,
            *,
            bootstrap=None,
            package=None,
            hub_package=None,
            client_package=None,
            version=None,
            demo=False):
    assert hub or clients
    assert not (hub and clients and package)
    # These assertions are checked in main.py

    if not hub_package:
        hub_package = package
    if not client_package:
        client_package = package
    if bootstrap:
        save_file(os.path.join(cf_remote_dir(), "policy_server.dat"),
                  bootstrap + "\n")
    if hub:
        log.debug("Installing hub package on '{}'".format(hub))
        install_host(hub,
                     hub=True,
                     package=hub_package,
                     bootstrap=bootstrap,
                     version=version,
                     demo=demo)
    for host in (clients or []):
        log.debug("Installing client package on '{}'".format(host))
        install_host(host,
                     hub=False,
                     package=client_package,
                     bootstrap=bootstrap,
                     version=version,
                     demo=demo)
    if demo and hub:
        print(
            "Your demo hub is ready: https://{}/ (Username: admin, Password: password)"
            .format(hub))
Beispiel #23
0
def download_package(url, path=None):
    if not path:
        filename = os.path.basename(url)
        directory = cf_remote_packages_dir()
        mkdir(directory)
        path = os.path.join(directory, filename)

    # Use "ab" to prevent truncation of the file in case it is already being
    # downloaded by a different thread.
    with open(path, "ab") as f:
        # Get an exclusive lock. If the file size is != 0 then it's already
        # downloaded, otherwise we download.
        fcntl.flock(f.fileno(), fcntl.LOCK_EX)
        st = os.stat(path)
        if st.st_size != 0:
            log.debug("Package '{}' already downloaded".format(path))
        else:
            print("Downloading package: '{}'".format(path))
            f.write(urllib.request.urlopen(url).read())
            f.flush()
        fcntl.flock(f.fileno(), fcntl.LOCK_UN)

    return path
Beispiel #24
0
def resolve_hosts(string, single=False, private_ips=False):
    log.debug("resolving hosts from '{}'".format(string))
    if is_file_string(string):
        names = expand_list_from_file(string)
    else:
        names = string.split(",")

    ret = []

    for name in names:
        if is_in_cloud_state(name):
            hosts = get_cloud_hosts(name, private_ips)
            ret.extend(hosts)
            log.debug("found in cloud, adding '{}'".format(hosts))
        else:
            ret.append(name)

    if single:
        if len(ret) != 1:
            user_error("'{}' must contain exactly 1 hostname or IP".format(string))
        return ret[0]
    else:
        return ret
Beispiel #25
0
def ssh_sudo(connection, cmd, errors=False):
    assert connection
    try:
        log.debug("Running(sudo) over SSH: '{}'".format(cmd))
        result = connection.run('sudo bash -c "{}"'.format(cmd.replace('"', r'\"')), hide=True)
        output = result.stdout.strip("\n")
        log.debug("'{}' -> '{}'".format(cmd, output))
        return output
    except UnexpectedExit as e:
        msg = "Sudo command unexpectedly exited: '{}'".format(cmd)
        if errors:
            print(e)
            log.error(msg)
        else:
            log.debug(str(e))
            log.debug(msg)
        return None
Beispiel #26
0
def ssh_cmd(connection, cmd, errors=False):
    assert connection
    try:
        log.debug("Running over SSH: '{}'".format(cmd))
        result = connection.run(cmd, hide=True)
        output = result.stdout.strip("\n")
        log.debug("'{}' -> '{}'".format(cmd, output))
        return output
    except UnexpectedExit as e:
        msg = "Non-sudo command unexpectedly exited: '{}'".format(cmd)
        if errors:
            print(e)
            log.error(msg)
        else:
            log.debug(str(e))
            log.debug(msg)
        return None
Beispiel #27
0
def ssh_cmd(connection, cmd, errors=False):
    assert connection
    try:
        log.debug("Running over SSH: '{}'".format(cmd))
        result = connection.run(cmd, hide=True)
        output = result.stdout.replace("\r\n", "\n").strip("\n")
        log.debug("'{}' -> '{}'".format(cmd, output))
        return output
    except UnexpectedExit as e:
        msg = "Non-sudo command unexpectedly exited: '{}'".format(cmd)
        if errors:
            print(e)
            log.error(msg)
        else:
            log.debug(str(e))
            log.debug(msg)
        return None
Beispiel #28
0
def deploy(hubs, masterfiles):
    if masterfiles.startswith(("http://", "https://")):
        urls = [masterfiles]
        paths = _download_urls(urls)
        assert len(paths) == 1
        masterfiles = paths[0]
        log.debug(f"Deploying downloaded: {masterfiles}")
    else:
        masterfiles = os.path.abspath(os.path.expanduser(masterfiles))
        log.debug(f"Deploy path expanded to: {masterfiles}")

    masterfiles = masterfiles.rstrip("/")

    if os.path.isfile(masterfiles):
        return deploy_tarball(hubs, masterfiles)

    if not os.path.isdir(masterfiles):
        log.error(f"'{masterfiles}' must be a directory")
        return 1

    directory = masterfiles

    if not directory.endswith("/masterfiles"):
        log.error(
            "The masterfiles directory to deploy must be called 'masterfiles'")
        return 1

    if os.path.isfile(f"{directory}/autogen.sh"):
        os.system(f"bash -c 'cd {directory} && ./autogen.sh 1>/dev/null 2>&1'")
        if not os.path.isfile(f"{directory}/promises.cf"):
            log.error(
                f"The autogen.sh script did not produce promises.cf in '{directory}'"
            )
            return 1
    elif os.path.isfile(f"{directory}/configure"):
        os.system(f"bash -c 'cd {directory} && ./configure 1>/dev/null 2>&1'")
        if not os.path.isfile(f"{directory}/promises.cf"):
            log.error(
                f"The configure script did not produce promises.cf in '{directory}'"
            )
            return 1
    else:
        log.debug(
            "No autogen.sh / configure found, assuming ready to install directory"
        )
        if not os.path.isfile(f"{directory}/promises.cf"):
            log.error(f"No promises.cf in '{directory}'")
            return 1

    assert (not cf_remote_dir().endswith("/"))
    tarball = cf_remote_dir() + "/masterfiles.tgz"
    above = directory[0:-len("/masterfiles")]
    os.system(f"rm -rf {tarball}")
    os.system(f"tar -czf {tarball} -C {above} masterfiles")
    return deploy_tarball(hubs, tarball)
Beispiel #29
0
def ssh_sudo(connection, cmd, errors=False):
    assert connection
    try:
        log.debug(f"Running(sudo) over SSH: '{cmd}'")
        escaped = cmd.replace('"', r"\"")
        sudo_cmd = f'sudo bash -c "{escaped}"'
        result = connection.run(sudo_cmd, hide=True, pty=True)
        output = result.stdout.strip("\n")
        log.debug(f"'{cmd}' -> '{output}'")
        return output
    except UnexpectedExit as e:
        msg = f"Sudo command unexpectedly exited: '{cmd}'"
        if errors:
            print(e)
            log.error(msg)
        else:
            log.debug(str(e))
            log.debug(msg)
        return None
Beispiel #30
0
def filter_artifacts(artifacts, tags, extension):
    if extension:
        artifacts = [a for a in artifacts if a.extension == extension]
    log.debug("Looking for tags: {}".format(tags))
    log.debug("In artifacts: {}".format(artifacts))
    for tag in tags or []:
        tag = canonify(tag)
        new_artifacts = [a for a in artifacts if tag in a.tags]
        # Have to force evaluation using list comprehension,
        # since we are overwriting artifacts
        if len(new_artifacts) > 0:
            artifacts = new_artifacts

    log.debug("Found artifacts: {}".format(artifacts))
    return artifacts
Beispiel #31
0
def connect(host, users=None):
    log.debug(f"Connecting to '{host}'")
    log.debug(f"users= '{users}'")
    if "@" in host:
        parts = host.split("@")
        assert len(parts) == 2
        host = parts[1]
        if not users:
            users = [parts[0]]
    if not users:
        users = [
            "Administrator",
            "admin",
            "ubuntu",
            "ec2-user",
            "centos",
            "vagrant",
            "root",
        ]
        # Similar to ssh, try own username first,
        # some systems will lock us out if we have too many failed attempts.
        if whoami() not in users:
            users = [whoami()] + users
    for user in users:
        try:
            log.debug(f"Attempting ssh: {user}@{host}")
            connect_kwargs = {}
            key = os.getenv("CF_REMOTE_SSH_KEY")
            if key:
                connect_kwargs["key_filename"] = os.path.expanduser(key)
            c = fabric.Connection(host=host,
                                  user=user,
                                  connect_kwargs=connect_kwargs)
            c.ssh_user = user
            c.ssh_host = host
            c.run("whoami", hide=True)
            return c
        except AuthenticationException:
            continue
    sys.exit(f"Could not ssh into '{host}'")
Beispiel #32
0
def mkdir(path):
    if not os.path.exists(path):
        log.info("Creating directory: '{}'".format(path))
        os.makedirs(path)
    else:
        log.debug("Directory already exists: '{}'".format(path))
Beispiel #33
0
def get_info(host, *, users=None, connection=None):
    log.debug("Getting info about '{}'".format(host))

    user, host = connection.ssh_user, connection.ssh_host
    data = OrderedDict()
    data["ssh_user"] = user
    data["ssh_host"] = host
    data["ssh"] = "{}@{}".format(user, host)
    data["whoami"] = ssh_cmd(connection, "whoami")
    systeminfo = ssh_cmd(connection, "systeminfo")
    if systeminfo:
        data["os"] = "windows"
        data["systeminfo"] = parse_systeminfo(systeminfo)
        data["package_tags"] = ["x86_64", "msi"]
        data["arch"] = "x86_64"
        agent = r"& 'C:\Program Files\Cfengine\bin\cf-agent.exe'"
        data["agent"] = agent
        version_cmd = powershell('{} -V'.format(agent))
        data["agent_version"] = parse_version(ssh_cmd(connection, version_cmd))
    else:
        data["os"] = "unix"
        data["uname"] = ssh_cmd(connection, "uname")
        data["arch"] = ssh_cmd(connection, "uname -m")
        data["os_release"] = os_release(
            ssh_cmd(connection, "cat /etc/os-release"))

        tags = []
        if data["os_release"]:
            distro = data["os_release"]["ID"]
            major = data["os_release"]["VERSION_ID"].split(".")[0]
            platform_tag = distro + major

            # Add tags with version number first, to filter by them first:
            tags.append(platform_tag)  # Example: ubuntu16
            if distro == "centos":
                tags.append("el" + major)

            # Then add more generic tags (lower priority):
            tags.append(distro)  # Example: ubuntu
            if distro == "centos":
                tags.append("rhel")
                tags.append("el")
        else:
            redhat_release = ssh_cmd(connection, "cat /etc/redhat-release")
            if redhat_release:
                # Examples:
                # CentOS release 6.10 (Final)
                # Red Hat Enterprise Linux release 8.0 (Ootpa)
                before, after = redhat_release.split(" release ")
                distro = "rhel"
                if before.lower().startswith("centos"):
                    distro = "centos"
                major = after.split(".")[0]
                tags.append(distro + major)
                tags.append("el" + major)
                if "rhel" not in tags:
                    tags.append("rhel" + major)

                tags.append(distro)
                if "rhel" not in tags:
                    tags.append("rhel")
                tags.append("el")

        data["package_tags"] = tags

        data["agent_location"] = ssh_cmd(connection, "which cf-agent")
        data["policy_server"] = ssh_cmd(connection,
                                        "cat /var/cfengine/policy_server.dat")

        agent = r'/var/cfengine/bin/cf-agent'
        data["agent"] = agent
        data["agent_version"] = parse_version(
            ssh_cmd(connection, "{} --version".format(agent)))

        data["bin"] = {}
        for bin in ["dpkg", "rpm", "yum", "apt", "pkg"]:
            path = ssh_cmd(connection, "which {}".format(bin))
            if path:
                data["bin"][bin] = path

    log.debug("JSON data from host info: \n" + pretty(data))
    return data
Beispiel #34
0
def info(hosts, users=None):
    assert hosts
    log.debug("hosts='{}'".format(hosts))
    for host in hosts:
        data = get_info(host, users=users)
        print_info(data)
Beispiel #35
0
def install(hubs,
            clients,
            *,
            bootstrap=None,
            package=None,
            hub_package=None,
            client_package=None,
            version=None,
            demo=False,
            call_collect=False,
            edition=None,
            remote_download=False,
            trust_keys=None):
    assert hubs or clients
    assert not (hubs and clients and package)
    assert (trust_keys is None) or hasattr(trust_keys, "__iter__")
    # These assertions are checked/ensured in main.py

    # If there are URLs in any of the package strings and remote_download is FALSE, download and replace with path:
    packages = (package, hub_package, client_package)
    if remote_download:
        package, hub_package, client_package = _verify_package_urls(packages)
    else:
        package, hub_package, client_package = _download_urls(packages)

    # If any of these are folders, transform them to lists of the files inside those folders:
    package = _maybe_packages_in_folder(package)
    hub_package = _maybe_packages_in_folder(hub_package)
    client_package = _maybe_packages_in_folder(client_package)

    # If --hub-package or --client-pacakge are not specified, use --package argument:
    if not hub_package:
        hub_package = package
    if not client_package:
        client_package = package

    if bootstrap:
        if type(bootstrap) is str:
            bootstrap = [bootstrap]
        save_file(os.path.join(cf_remote_dir(), "policy_server.dat"),
                  "\n".join(bootstrap + [""]))

    hub_jobs = []
    if hubs:
        show_host_info = (len(hubs) == 1)
        if type(hubs) is str:
            hubs = [hubs]
        for index, hub in enumerate(hubs):
            log.debug("Installing {} hub package on '{}'".format(edition, hub))
            hub_jobs.append(
                HostInstaller(
                    hub,
                    hub=True,
                    packages=hub_package,
                    bootstrap=bootstrap[index %
                                        len(bootstrap)] if bootstrap else None,
                    version=version,
                    demo=demo,
                    call_collect=call_collect,
                    edition=edition,
                    show_info=show_host_info,
                    remote_download=remote_download,
                    trust_keys=trust_keys))

    errors = 0
    if hub_jobs:
        with Pool(len(hub_jobs)) as hubs_install_pool:
            hubs_install_pool.map(lambda job: job.run(), hub_jobs)
        errors = sum(job.errors for job in hub_jobs)

    if errors > 0:
        s = "s" if errors > 1 else ""
        log.error(
            f"{errors} error{s} encountered while installing hub packages, aborting..."
        )
        return errors

    client_jobs = []
    show_host_info = (clients and (len(clients) == 1))
    for index, host in enumerate(clients or []):
        log.debug("Installing {} client package on '{}'".format(edition, host))
        client_jobs.append(
            HostInstaller(
                host,
                hub=False,
                packages=client_package,
                bootstrap=bootstrap[index %
                                    len(bootstrap)] if bootstrap else None,
                version=version,
                demo=demo,
                edition=edition,
                show_info=show_host_info,
                remote_download=remote_download,
                trust_keys=trust_keys))

    if client_jobs:
        with Pool(len(client_jobs)) as clients_install_pool:
            clients_install_pool.map(lambda job: job.run(), client_jobs)
        errors += sum(job.errors for job in client_jobs)

    if demo and hubs:
        for hub in hubs:
            print(
                "Your demo hub is ready: https://{}/ (Username: admin, Password: password)"
                .format(strip_user(hub)))

    if errors > 0:
        s = "s" if errors > 1 else ""
        log.error(
            f"{errors} error{s} encountered while installing client packages")

    return errors