Exemplo n.º 1
0
def __init__(conf: Configuration, name: str, hard: bool, own: bool):
    ostack = OpenStack(conf)

    def __work_unit(value: OpenStackVMInfo) -> bool:
        return ostack.start_instance(value)

    so = StatusOutput(__work_unit,
                      pool_size=5,
                      additional_errors=ostack.last_errors)
    servers = ostack.get_server_by_cluster(
        name,
        sort=True,
        filter_func=lambda x: x.state in ServerPowerState.stop_states(),
        only_owned=own)

    if not servers:
        print("No matches or already started")
        return

    if Console.confirm_operation("reboot", servers):
        flatten_servers = [
            server for server_pair in servers.values()
            for server in server_pair
        ]

        so.start("Rebooting nodes", objects=flatten_servers)
    else:
        print("Aborted....")
Exemplo n.º 2
0
def host_selector(ostack: OpenStack, name: str, node_index: Optional[int] = None, own: bool = False) -> OpenStackVMInfo:
  if name == "None":
    name = ""

  if name and node_index == -1:
    _name, _, _node_index = name.rpartition("-")

    try:
      node_index = int(_node_index)
      name = _name
    except (ValueError, TypeError):
      pass

  if "." in name:
    name, _ = name.split(".")

  search_result: Dict[str, List[OpenStackVMInfo]] = ostack.get_server_by_cluster(name, sort=True, only_owned=own)
  to = TableOutput(
    TableColumn("Cluster name", 40),
    print_row_number=True
  )
  if len(search_result.keys()) > 1:
    to.print_header()
    for cluster_name in search_result.keys():
      to.print_row(cluster_name)

    selection: int = Console.ask("Choose cluster from the list", int)
    try:
      name = list(search_result.keys())[selection:][0]
    except IndexError:
      raise ValueError("Wrong selection, please select item within an provided range")
  elif search_result:
    name = list(search_result.keys())[0]
  else:
    raise ValueError(f"No matching cluster matching pattern'{name}' found")

  nodes: List[OpenStackVMInfo] = search_result[name]
  if node_index == -1:
    if len(nodes) > 1:
      to = TableOutput(
        TableColumn("IP", 18),
        TableColumn("Host name", 40),

        print_row_number=True
      )
      to.print_header()
      for node in nodes:
        to.print_row(node.ip_address, node.fqdn)
      node_index: int = Console.ask("Choose host from the list", int)
      if node_index > len(nodes):
        raise ValueError("Wrong selection, please select item within an provided range")
    else:
      node_index = 0
  else:
    node_index -= 1    # the node name starts for 1, while list from 0

  try:
    return nodes[node_index]
  except IndexError:
    raise ValueError("Unknown host name, please check the name")
Exemplo n.º 3
0
def __init__(conf: Configuration, search_pattern: str, debug: bool, own: bool):
  vh: ValueHolder = ValueHolder(3)
  def __fake_filter(s: OpenStackVMInfo):
    vh.set_if_bigger(WidthConst.max_fqdn_len, len(s.fqdn))
    vh.set_if_bigger(WidthConst.max_key_len, len(s.key_name))
    vh.set_if_bigger(WidthConst.max_net_len, len(s.net_name))
    return False

  ostack = OpenStack(conf, debug=debug)
  clusters = ostack.get_server_by_cluster(search_pattern=search_pattern, sort=True, only_owned=own,
                                          filter_func=__fake_filter)

  print_cluster(clusters, vh, ostack)
Exemplo n.º 4
0
def __init__(conf: Configuration, search_pattern: str, own: bool):
  ostack = OpenStack(conf)

  vh = ValueHolder(2)
  def __fake_filter(s: OpenStackVMInfo):
    vh.set_if_bigger(WidthConst.max_cluster_name, len(s.cluster_name))
    vh.set_if_bigger(WidthConst.max_vm_type_len, len(s.flavor.name))
    return False

  clusters = ostack.get_server_by_cluster(search_pattern=search_pattern, sort=True, only_owned=own,
                                          filter_func=__fake_filter)

  if search_pattern and len(clusters) == 0:
    print(f"Query '{search_pattern}' returned no match")
    return

  print_cluster(clusters, vh)
Exemplo n.º 5
0
def __init__(conf: Configuration, name: str, node_number: int, user_name: str, use_password: bool, use_key: str,
             own: bool, port: int, internal: bool):
  ostack = OpenStack(conf)
  if name == "None":
    name = ""

  if use_key == "None":
    use_key = None

  if name and node_number == -1:
    _name, _, _node_number = name.rpartition("-")

    try:
      node_number = int(_node_number)
      name = _name
    except (ValueError, TypeError):
      pass

  if "." in name:
    name, _ = name.split(".")

  search_result: Dict[str, List[OpenStackVMInfo]] = ostack.get_server_by_cluster(name, sort=True, only_owned=own)
  to = TableOutput(
    TableColumn("Cluster name", 40),
    print_row_number=True
  )
  if len(search_result.keys()) > 1:
    to.print_header()
    for cluster_name in search_result.keys():
      to.print_row(cluster_name)

    selection: int = Console.ask("Choose cluster from the list", int)
    try:
      name = list(search_result.keys())[selection:][0]
    except IndexError:
      raise ValueError("Wrong selection, please select item within an provided range")
  elif search_result:
    name = list(search_result.keys())[0]
  else:
    raise ValueError(f"No matching cluster matching pattern'{name}' found")

  nodes: List[OpenStackVMInfo] = search_result[name]
  if node_number == -1:
    if len(nodes) > 1:
      to = TableOutput(
        TableColumn("IP", 18),
        TableColumn("Host name", 40),

        print_row_number=True
      )
      to.print_header()
      for node in nodes:
        to.print_row(node.ip_address, node.fqdn)
      node_number: int = Console.ask("Choose host from the list", int)
      if node_number > len(nodes):
        raise ValueError("Wrong selection, please select item within an provided range")
    else:
      node_number = 0
  else:
    node_number -= 1    # the node name starts for 1, while list from 0

  try:
    node: OpenStackVMInfo = nodes[node_number]
  except IndexError:
    raise ValueError("Unknown host name, please check the name")

  print(f"Establishing connection to {node.fqdn}({node.ip_address}) as '{user_name}' user...")
  if use_password:
    _open_console(internal, node.ip_address, port=port, user_name=user_name, password=True)
  else:
    if not os.path.exists(conf.local_key_dir):
      os.makedirs(conf.local_key_dir, exist_ok=True)

    if not use_key and node.key_name and node.key_name in conf.key_names and conf.get_key(node.key_name).private_key:
      #PKCS8 format -> openssl
      pkcs8_frmt_B = "-----BEGIN PRIVATE KEY-----"
      pkcs8_frmt_E ="-----END PRIVATE KEY-----"
      openssl_frmt_B = "-----BEGIN RSA PRIVATE KEY-----"
      openssl_frmt_E = "-----END RSA PRIVATE KEY-----"

      key = conf.get_key(node.key_name).private_key
      if pkcs8_frmt_B in key:
        key = key.replace(pkcs8_frmt_B, openssl_frmt_B)

      if pkcs8_frmt_E in key:
        key = key.replace(pkcs8_frmt_E, openssl_frmt_E)

      use_key = os.path.join(conf.local_key_dir, node.key_name) + ".key"
      with open(use_key, "w+", encoding="UTF-8") as f:
        f.write(key)
      try:
        os.chmod(use_key, 0o600)
      except OSError:
        pass
    else:
      raise ValueError("No custom key provided nor private key found in the key storage. Please add private key to"
                       " storage or use custom one with 'use-key' argument")

    _open_console(internal, node.ip_address, user_name=user_name, port=port, key_file=use_key)
Exemplo n.º 6
0
def __init__(conf: Configuration, name: str, count: int, flavor: str,
             image: str, key: str, password: str):
    def __work_unit(x: OpenStackVMInfo) -> bool:
        while True:
            if x.status == ServerState.active:
                return True

            if x.status not in [
                    ServerState.building, ServerState.build, ServerState.active
            ]:
                return False

            sleep(2)
            #  ToDo: short term cache data by reservation_id
            x = ostack.get_server_by_id(x)

    # ======================================================================
    ostack = OpenStack(conf)
    vh = ValueHolder(2)

    def __filter(vm: OpenStackVMInfo) -> bool:
        r = not str(vm.name).startswith(name)
        if not r:
            vh.set_if_bigger(0, len(vm.cluster_name))
            vh.set_if_bigger(1, len(vm.flavor.name))
        return r

    servers = ostack.get_server_by_cluster(name, True, filter_func=__filter)
    if len(servers) > 1:
        Console.print_warning(
            f"Cluster with name '{Colors.BRIGHT_WHITE.wrap(name)}' already exists, instance would be not be created"
        )
        print_cluster(servers, vh)
        return
    elif len(servers) == 1:
        Console.print_info(
            f"The cluster already exists, will add requested amount of hosts to the cluster"
        )
        with Console.status_context(
                f"Obtaining cluster information from existing {name}..."):
            cluster_name, hosts = next(iter(servers.items()))
            cluster_name: str = cluster_name
            hosts: List[OpenStackVMInfo] = hosts
            host: OpenStackVMInfo = hosts[0]

            # re-calculate host names
            last_host_name = hosts[-1:][0].name
            _, _, num = last_host_name.rpartition("-")

            _start_num: int = 1
            if num and num.isnumeric():
                _start_num: int = int(num) + 1

            name: List[str] = [
                f"{cluster_name}-{num}"
                for num in range(_start_num, _start_num + count)
            ]

            image: OSImageInfo = ostack.get_os_image(host.image)
            img_flavor: OSFlavor = host.flavor
            _default_key = ostack.get_keypairs()[0] if ostack.get_keypairs(
            ) else None
            _key = ostack.get_keypair(host.key_name, _default_key)
            _pass = conf.default_vm_password if not password else password

            print(f"   |Image flavor to use: {img_flavor.name}")
            print(f"   |Image to use       : {image.alias}")
            print(f"   |Key to use         : {_key.name}")
            print(f"   |Hosts to add       : {', '.join(name)}")
    else:
        with Console.status_context("Resolving cluster configuration"):
            image: List[OSImageInfo] = list(ostack.get_image_by_alias(image))
            if not image:
                raise RuntimeError("Cannot resolve image name for the request")

            image: OSImageInfo = image[0]
            img_flavor = ostack.get_flavor(image, flavor)
            _default_key = ostack.get_keypairs()[0] if ostack.get_keypairs(
            ) else None
            _key = _default_key if not key else ostack.get_keypair(
                key, _default_key)
            _pass = conf.default_vm_password if not password else password

    # == create nodes

    so = StatusOutput(__work_unit,
                      pool_size=2,
                      additional_errors=ostack.last_errors)

    with Console.status_context("Asking for node creation"):
        servers = ostack.create_instances(cluster_names=name,
                                          image=image,
                                          flavor=img_flavor,
                                          password=_pass,
                                          count=count,
                                          ssh_key=_key)
        if not servers:
            so.check_issues()
            return

    so.start("Creating nodes ", objects=servers)

    # == Configure nodes
    def __work_unit_waiter(x: OpenStackVMInfo) -> bool:
        tries: int = 0
        while tries < 200:
            log = ostack.get_server_console_log(x.id)
            for l in log:
                if "finished" in l or "login:"******"Configure nodes", servers)

    console = ostack.get_server_console_log(servers[0], grep_by="cloud-init")

    to = TableOutput(TableColumn("Name", 15), TableColumn("Value", 30))

    to.print_header(custom_header="SUMMARY")

    for line in console:
        if "@users@" in line:
            users = line.split("@users@:")[1].strip().split(" ")
            to.print_row("Accounts", ",".join(users))

    to.print_row("Key", _key.name if _key else "Not used")
    to.print_row("Password", _pass)