|
| 1 | +from aztk import models |
| 2 | +from aztk.internal import cluster_data |
| 3 | +from aztk.utils import ssh as ssh_lib |
| 4 | + |
| 5 | +from .helpers import (create_user_on_cluster, create_user_on_node, delete_user_on_cluster, delete_user_on_node, |
| 6 | + generate_user_on_cluster, generate_user_on_node, get_application_log, get_remote_login_settings, |
| 7 | + node_run, run, ssh_into_node) |
| 8 | + |
| 9 | + |
| 10 | +class BaseOperations: |
| 11 | + """Base operations that all other operations have as an attribute |
| 12 | +
|
| 13 | + Attributes: |
| 14 | + batch_client (:obj:`azure.batch.batch_service_client.BatchServiceClient`): Client used to interact with the |
| 15 | + Azure Batch service. |
| 16 | + blob_client (:obj:`azure.storage.blob.BlockBlobService`): Client used to interact with the Azure Storage |
| 17 | + Blob service. |
| 18 | + secrets_configuration (:obj:`aztk.models.SecretsConfiguration`): Model that holds AZTK secrets used to authenticate |
| 19 | + with Azure and the clusters. |
| 20 | + """ |
| 21 | + |
| 22 | + def __init__(self, context): |
| 23 | + self.batch_client = context['batch_client'] |
| 24 | + self.blob_client = context['blob_client'] |
| 25 | + self.secrets_configuration = context['secrets_configuration'] |
| 26 | + |
| 27 | + def get_cluster_config(self, id: str) -> models.ClusterConfiguration: |
| 28 | + """Open an ssh tunnel to a node |
| 29 | +
|
| 30 | + Args: |
| 31 | + id (:obj:`str`): the id of the cluster the node is in |
| 32 | + node_id (:obj:`str`): the id of the node to open the ssh tunnel to |
| 33 | + username (:obj:`str`): the username to authenticate the ssh session |
| 34 | + ssh_key (:obj:`str`, optional): ssh public key to create the user with, must use ssh_key |
| 35 | + or password. Defaults to None. |
| 36 | + password (:obj:`str`, optional): password for the user, must use ssh_key or password. Defaults to None. |
| 37 | + port_forward_list (:obj:`List[PortForwardingSpecification`, optional): list of PortForwardingSpecifications. |
| 38 | + The defined ports will be forwarded to the client. |
| 39 | + internal (:obj:`bool`, optional): if True, this will connect to the node using its internal IP. |
| 40 | + Only use this if running within the same VNET as the cluster. Defaults to False. |
| 41 | +
|
| 42 | + Returns: |
| 43 | + :obj:`aztk.models.ClusterConfiguration`: Object representing the cluster's configuration |
| 44 | + """ |
| 45 | + return self.get_cluster_data(id).read_cluster_config() |
| 46 | + |
| 47 | + def get_cluster_data(self, id: str) -> cluster_data.ClusterData: |
| 48 | + """Gets the ClusterData object to manage data related to the given cluster |
| 49 | +
|
| 50 | + Args: |
| 51 | + id (:obj:`str`): the id of the cluster to get |
| 52 | +
|
| 53 | + Returns: |
| 54 | + :obj:`aztk.models.ClusterData`: Object used to manage the data and storage functions for a cluster |
| 55 | + """ |
| 56 | + return cluster_data.ClusterData(self.blob_client, id) |
| 57 | + |
| 58 | + def ssh_into_node(self, id, node_id, username, ssh_key=None, password=None, port_forward_list=None, internal=False): |
| 59 | + """Open an ssh tunnel to a node |
| 60 | +
|
| 61 | + Args: |
| 62 | + id (:obj:`str`): the id of the cluster the node is in |
| 63 | + node_id (:obj:`str`): the id of the node to open the ssh tunnel to |
| 64 | + username (:obj:`str`): the username to authenticate the ssh session |
| 65 | + ssh_key (:obj:`str`, optional): ssh public key to create the user with, must use ssh_key or password. Defaults to None. |
| 66 | + password (:obj:`str`, optional): password for the user, must use ssh_key or password. Defaults to None. |
| 67 | + port_forward_list (:obj:`List[PortForwardingSpecification`, optional): list of PortForwardingSpecifications. |
| 68 | + The defined ports will be forwarded to the client. |
| 69 | + internal (:obj:`bool`, optional): if True, this will connect to the node using its internal IP. |
| 70 | + Only use this if running within the same VNET as the cluster. Defaults to False. |
| 71 | +
|
| 72 | + Returns: |
| 73 | + :obj:`None` |
| 74 | + """ |
| 75 | + ssh_into_node.ssh_into_node(self, id, node_id, username, ssh_key, password, port_forward_list, internal) |
| 76 | + |
| 77 | + def create_user_on_node(self, id, node_id, username, ssh_key=None, password=None): |
| 78 | + """Create a user on a node |
| 79 | +
|
| 80 | + Args: |
| 81 | + id (:obj:`str`): id of the cluster to create the user on. |
| 82 | + node_id (:obj:`str`): id of the node in the cluster to create the user on. |
| 83 | + username (:obj:`str`): name of the user to create. |
| 84 | + ssh_key (:obj:`str`, optional): ssh public key to create the user with, must use ssh_key or password. |
| 85 | + password (:obj:`str`, optional): password for the user, must use ssh_key or password. |
| 86 | +
|
| 87 | + Returns: |
| 88 | + :obj:`None` |
| 89 | + """ |
| 90 | + return create_user_on_node.create_user_on_node(self, id, node_id, username, ssh_key, password) |
| 91 | + |
| 92 | + #TODO: remove nodes as param |
| 93 | + def create_user_on_cluster(self, id, nodes, username, ssh_pub_key=None, password=None): |
| 94 | + """Create a user on every node in the cluster |
| 95 | +
|
| 96 | + Args: |
| 97 | + username (:obj:`str`): name of the user to create. |
| 98 | + id (:obj:`str`): id of the cluster to create the user on. |
| 99 | + nodes (:obj:`List[ComputeNode]`): list of nodes to create the user on |
| 100 | + ssh_key (:obj:`str`, optional): ssh public key to create the user with, must use ssh_key or password. Defaults to None. |
| 101 | + password (:obj:`str`, optional): password for the user, must use ssh_key or password. Defaults to None. |
| 102 | +
|
| 103 | + Returns: |
| 104 | + :obj:`None` |
| 105 | + """ |
| 106 | + return create_user_on_cluster.create_user_on_cluster(self, id, nodes, username, ssh_pub_key, password) |
| 107 | + |
| 108 | + def generate_user_on_node(self, id, node_id): |
| 109 | + """Create a user with an autogenerated username and ssh_key on the given node. |
| 110 | +
|
| 111 | + Args: |
| 112 | + id (:obj:`str`): the id of the cluster to generate the user on. |
| 113 | + node_id (:obj:`str`): the id of the node in the cluster to generate the user on. |
| 114 | +
|
| 115 | + Returns: |
| 116 | + :obj:`tuple`: A tuple of the form (username: :obj:`str`, ssh_key: :obj:`Cryptodome.PublicKey.RSA`) |
| 117 | + """ |
| 118 | + return generate_user_on_node.generate_user_on_node(self, id, node_id) |
| 119 | + |
| 120 | + #TODO: remove nodes as param |
| 121 | + def generate_user_on_cluster(self, id, nodes): |
| 122 | + """Create a user with an autogenerated username and ssh_key on the cluster |
| 123 | +
|
| 124 | + Args: |
| 125 | + id (:obj:`str`): the id of the cluster to generate the user on. |
| 126 | + node_id (:obj:`str`): the id of the node in the cluster to generate the user on. |
| 127 | +
|
| 128 | + Returns: |
| 129 | + :obj:`tuple`: A tuple of the form (username: :obj:`str`, ssh_key: :obj:`Cryptodome.PublicKey.RSA`) |
| 130 | + """ |
| 131 | + return generate_user_on_cluster.generate_user_on_cluster(self, id, nodes) |
| 132 | + |
| 133 | + def delete_user_on_node(self, id: str, node_id: str, username: str) -> str: |
| 134 | + """Delete a user on a node |
| 135 | +
|
| 136 | + Args: |
| 137 | + id (:obj:`str`): the id of the cluster to delete the user on. |
| 138 | + node_id (:obj:`str`): the id of the node in the cluster to delete the user on. |
| 139 | + username (:obj:`str`): the name of the user to delete. |
| 140 | +
|
| 141 | + Returns: |
| 142 | + :obj:`None` |
| 143 | + """ |
| 144 | + return delete_user_on_node.delete_user(self, id, node_id, username) |
| 145 | + |
| 146 | + #TODO: remove nodes as param |
| 147 | + def delete_user_on_cluster(self, username, id, nodes): |
| 148 | + """Delete a user on every node in the cluster |
| 149 | +
|
| 150 | + Args: |
| 151 | + id (:obj:`str`): the id of the cluster to delete the user on. |
| 152 | + node_id (:obj:`str`): the id of the node in the cluster to delete the user on. |
| 153 | + username (:obj:`str`): the name of the user to delete. |
| 154 | +
|
| 155 | + Returns: |
| 156 | + :obj:`None` |
| 157 | + """ |
| 158 | + return delete_user_on_cluster.delete_user_on_cluster(self, username, id, nodes) |
| 159 | + |
| 160 | + def node_run(self, id, node_id, command, internal, container_name=None, timeout=None): |
| 161 | + """Run a bash command on the given node |
| 162 | +
|
| 163 | + Args: |
| 164 | + id (:obj:`str`): the id of the cluster to run the command on. |
| 165 | + node_id (:obj:`str`): the id of the node in the cluster to run the command on. |
| 166 | + command (:obj:`str`): the bash command to execute on the node. |
| 167 | + internal (:obj:`bool`): if True, this will connect to the node using its internal IP. |
| 168 | + Only use this if running within the same VNET as the cluster. Defaults to False. |
| 169 | + container_name=None (:obj:`str`, optional): the name of the container to run the command in. |
| 170 | + If None, the command will run on the host VM. Defaults to None. |
| 171 | + timeout=None (:obj:`str`, optional): The timeout in seconds for establishing a connection to the node. |
| 172 | + Defaults to None. |
| 173 | +
|
| 174 | + Returns: |
| 175 | + :obj:`aztk.models.NodeOutput`: object containing the output of the run command |
| 176 | + """ |
| 177 | + return node_run.node_run(self, id, node_id, command, internal, container_name, timeout) |
| 178 | + |
| 179 | + def get_remote_login_settings(self, id: str, node_id: str): |
| 180 | + """Get the remote login information for a node in a cluster |
| 181 | +
|
| 182 | + Args: |
| 183 | + id (:obj:`str`): the id of the cluster the node is in |
| 184 | + node_id (:obj:`str`): the id of the node in the cluster |
| 185 | +
|
| 186 | + Returns: |
| 187 | + :obj:`aztk.models.RemoteLogin`: Object that contains the ip address and port combination to login to a node |
| 188 | + """ |
| 189 | + return get_remote_login_settings.get_remote_login_settings(self, id, node_id) |
| 190 | + |
| 191 | + def run(self, id, command, internal, container_name=None, timeout=None): |
| 192 | + """Run a bash command on every node in the cluster |
| 193 | +
|
| 194 | + Args: |
| 195 | + id (:obj:`str`): the id of the cluster to run the command on. |
| 196 | + command (:obj:`str`): the bash command to execute on the node. |
| 197 | + internal (:obj:`bool`): if true, this will connect to the node using its internal IP. |
| 198 | + Only use this if running within the same VNET as the cluster. Defaults to False. |
| 199 | + container_name=None (:obj:`str`, optional): the name of the container to run the command in. |
| 200 | + If None, the command will run on the host VM. Defaults to None. |
| 201 | + timeout=None (:obj:`str`, optional): The timeout in seconds for establishing a connection to the node. |
| 202 | + Defaults to None. |
| 203 | +
|
| 204 | + Returns: |
| 205 | + :obj:`List[azkt.models.NodeOutput]`: list of NodeOutput objects containing the output of the run command |
| 206 | + """ |
| 207 | + return run.cluster_run(self, id, command, internal, container_name, timeout) |
| 208 | + |
| 209 | + def get_application_log(self, id: str, application_name: str, tail=False, current_bytes: int = 0): |
| 210 | + """Get the log for a running or completed application |
| 211 | +
|
| 212 | + Args: |
| 213 | + id (:obj:`str`): the id of the cluster to run the command on. |
| 214 | + application_name (:obj:`str`): str |
| 215 | + tail (:obj:`bool`, optional): If True, get the remaining bytes after current_bytes. Otherwise, the whole log will be retrieved. |
| 216 | + Only use this if streaming the log as it is being written. Defaults to False. |
| 217 | + current_bytes (:obj:`int`): Specifies the last seen byte, so only the bytes after current_bytes are retrieved. |
| 218 | + Only useful is streaming the log as it is being written. Only used if tail is True. |
| 219 | +
|
| 220 | + Returns: |
| 221 | + :obj:`aztk.models.ApplicationLog`: a model representing the output of the application. |
| 222 | + """ |
| 223 | + return get_application_log.get_application_log(self, id, application_name, tail, current_bytes) |
0 commit comments