from typing import Optional, Any, List, Dict from phi.docker.api_client import DockerApiClient from phi.docker.resource.base import DockerResource from phi.utils.log import logger class DockerNetwork(DockerResource): resource_type: str = "Network" # driver (str) – Name of the driver used to create the network driver: Optional[str] = None # options (dict) – Driver options as a key-value dictionary options: Optional[Dict[str, Any]] = None # check_duplicate (bool) – Request daemon to check for networks with same name. Default: None. auto_remove: Optional[bool] = None # internal (bool) – Restrict external access to the network. Default False. internal: Optional[bool] = None # labels (dict) – Map of labels to set on the network. Default None. labels: Optional[Dict[str, Any]] = None # enable_ipv6 (bool) – Enable IPv6 on the network. Default False. enable_ipv6: Optional[bool] = None # attachable (bool) – If enabled, and the network is in the global scope # non-service containers on worker nodes will be able to connect to the network. attachable: Optional[bool] = None # scope (str) – Specify the network’s scope (local, global or swarm) scope: Optional[str] = None # ingress (bool) – If set, create an ingress network which provides the routing-mesh in swarm mode. ingress: Optional[bool] = None # Set skip_delete=True so that the network is not deleted when the `phi ws down` command is run skip_delete: bool = True skip_update: bool = True def _create(self, docker_client: DockerApiClient) -> bool: """Creates the Network on docker Args: docker_client: The DockerApiClient for the current cluster """ from docker import DockerClient from docker.models.networks import Network logger.debug("Creating: {}".format(self.get_resource_name())) network_name: Optional[str] = self.name network_object: Optional[Network] = None try: _api_client: DockerClient = docker_client.api_client network_object = _api_client.networks.create(network_name) if network_object is not None: logger.debug("Network Created: {}".format(network_object.name)) else: logger.debug("Network could not be created") # logger.debug("Network {}".format(network_object.attrs)) except Exception: raise # By this step the network should be created # Validate that the network is created logger.debug("Validating network is created") if network_object is not None: # TODO: validate that the network was actually created self.active_resource = network_object return True logger.debug("Network not found") return False def _read(self, docker_client: DockerApiClient) -> Any: """Returns a Network object if the network is active Args: docker_client: The DockerApiClient for the current cluster""" from docker import DockerClient from docker.models.networks import Network logger.debug("Reading: {}".format(self.get_resource_name())) # Get active networks from the docker_client network_name: Optional[str] = self.name try: _api_client: DockerClient = docker_client.api_client network_list: Optional[List[Network]] = _api_client.networks.list() # logger.debug("network_list: {}".format(network_list)) if network_list is not None: for network in network_list: if network.name == network_name: logger.debug(f"Network {network_name} exists") self.active_resource = network return network except Exception: logger.debug(f"Network {network_name} not found") return None def _delete(self, docker_client: DockerApiClient) -> bool: """Deletes the Network from docker Args: docker_client: The DockerApiClient for the current cluster """ from docker.models.networks import Network from docker.errors import NotFound logger.debug("Deleting: {}".format(self.get_resource_name())) network_object: Optional[Network] = self._read(docker_client) # Return True if there is no Network to delete if network_object is None: return True # Delete Network try: self.active_resource = None network_object.remove() except Exception as e: logger.exception("Error while deleting network: {}".format(e)) # Validate that the network is deleted logger.debug("Validating network is deleted") try: logger.debug("Reloading network_object: {}".format(network_object)) network_object.reload() except NotFound: logger.debug("Got NotFound Exception, Network is deleted") return True return False