1from docker.api import APIClient 2from docker.errors import APIError 3from .resource import Model 4 5 6class Swarm(Model): 7 """ 8 The server's Swarm state. This a singleton that must be reloaded to get 9 the current state of the Swarm. 10 """ 11 id_attribute = 'ID' 12 13 def __init__(self, *args, **kwargs): 14 super().__init__(*args, **kwargs) 15 if self.client: 16 try: 17 self.reload() 18 except APIError as e: 19 # FIXME: https://github.com/docker/docker/issues/29192 20 if e.response.status_code not in (406, 503): 21 raise 22 23 @property 24 def version(self): 25 """ 26 The version number of the swarm. If this is not the same as the 27 server, the :py:meth:`update` function will not work and you will 28 need to call :py:meth:`reload` before calling it again. 29 """ 30 return self.attrs.get('Version').get('Index') 31 32 def get_unlock_key(self): 33 return self.client.api.get_unlock_key() 34 get_unlock_key.__doc__ = APIClient.get_unlock_key.__doc__ 35 36 def init(self, advertise_addr=None, listen_addr='0.0.0.0:2377', 37 force_new_cluster=False, default_addr_pool=None, 38 subnet_size=None, data_path_addr=None, **kwargs): 39 """ 40 Initialize a new swarm on this Engine. 41 42 Args: 43 advertise_addr (str): Externally reachable address advertised to 44 other nodes. This can either be an address/port combination in 45 the form ``192.168.1.1:4567``, or an interface followed by a 46 port number, like ``eth0:4567``. If the port number is omitted, 47 the port number from the listen address is used. 48 49 If not specified, it will be automatically detected when 50 possible. 51 listen_addr (str): Listen address used for inter-manager 52 communication, as well as determining the networking interface 53 used for the VXLAN Tunnel Endpoint (VTEP). This can either be 54 an address/port combination in the form ``192.168.1.1:4567``, 55 or an interface followed by a port number, like ``eth0:4567``. 56 If the port number is omitted, the default swarm listening port 57 is used. Default: ``0.0.0.0:2377`` 58 force_new_cluster (bool): Force creating a new Swarm, even if 59 already part of one. Default: False 60 default_addr_pool (list of str): Default Address Pool specifies 61 default subnet pools for global scope networks. Each pool 62 should be specified as a CIDR block, like '10.0.0.0/8'. 63 Default: None 64 subnet_size (int): SubnetSize specifies the subnet size of the 65 networks created from the default subnet pool. Default: None 66 data_path_addr (string): Address or interface to use for data path 67 traffic. For example, 192.168.1.1, or an interface, like eth0. 68 task_history_retention_limit (int): Maximum number of tasks 69 history stored. 70 snapshot_interval (int): Number of logs entries between snapshot. 71 keep_old_snapshots (int): Number of snapshots to keep beyond the 72 current snapshot. 73 log_entries_for_slow_followers (int): Number of log entries to 74 keep around to sync up slow followers after a snapshot is 75 created. 76 heartbeat_tick (int): Amount of ticks (in seconds) between each 77 heartbeat. 78 election_tick (int): Amount of ticks (in seconds) needed without a 79 leader to trigger a new election. 80 dispatcher_heartbeat_period (int): The delay for an agent to send 81 a heartbeat to the dispatcher. 82 node_cert_expiry (int): Automatic expiry for nodes certificates. 83 external_ca (dict): Configuration for forwarding signing requests 84 to an external certificate authority. Use 85 ``docker.types.SwarmExternalCA``. 86 name (string): Swarm's name 87 labels (dict): User-defined key/value metadata. 88 signing_ca_cert (str): The desired signing CA certificate for all 89 swarm node TLS leaf certificates, in PEM format. 90 signing_ca_key (str): The desired signing CA key for all swarm 91 node TLS leaf certificates, in PEM format. 92 ca_force_rotate (int): An integer whose purpose is to force swarm 93 to generate a new signing CA certificate and key, if none have 94 been specified. 95 autolock_managers (boolean): If set, generate a key and use it to 96 lock data stored on the managers. 97 log_driver (DriverConfig): The default log driver to use for tasks 98 created in the orchestrator. 99 100 Returns: 101 (str): The ID of the created node. 102 103 Raises: 104 :py:class:`docker.errors.APIError` 105 If the server returns an error. 106 107 Example: 108 109 >>> client.swarm.init( 110 advertise_addr='eth0', listen_addr='0.0.0.0:5000', 111 force_new_cluster=False, default_addr_pool=['10.20.0.0/16], 112 subnet_size=24, snapshot_interval=5000, 113 log_entries_for_slow_followers=1200 114 ) 115 116 """ 117 init_kwargs = { 118 'advertise_addr': advertise_addr, 119 'listen_addr': listen_addr, 120 'force_new_cluster': force_new_cluster, 121 'default_addr_pool': default_addr_pool, 122 'subnet_size': subnet_size, 123 'data_path_addr': data_path_addr, 124 } 125 init_kwargs['swarm_spec'] = self.client.api.create_swarm_spec(**kwargs) 126 node_id = self.client.api.init_swarm(**init_kwargs) 127 self.reload() 128 return node_id 129 130 def join(self, *args, **kwargs): 131 return self.client.api.join_swarm(*args, **kwargs) 132 join.__doc__ = APIClient.join_swarm.__doc__ 133 134 def leave(self, *args, **kwargs): 135 return self.client.api.leave_swarm(*args, **kwargs) 136 leave.__doc__ = APIClient.leave_swarm.__doc__ 137 138 def reload(self): 139 """ 140 Inspect the swarm on the server and store the response in 141 :py:attr:`attrs`. 142 143 Raises: 144 :py:class:`docker.errors.APIError` 145 If the server returns an error. 146 """ 147 self.attrs = self.client.api.inspect_swarm() 148 149 def unlock(self, key): 150 return self.client.api.unlock_swarm(key) 151 unlock.__doc__ = APIClient.unlock_swarm.__doc__ 152 153 def update(self, rotate_worker_token=False, rotate_manager_token=False, 154 rotate_manager_unlock_key=False, **kwargs): 155 """ 156 Update the swarm's configuration. 157 158 It takes the same arguments as :py:meth:`init`, except 159 ``advertise_addr``, ``listen_addr``, and ``force_new_cluster``. In 160 addition, it takes these arguments: 161 162 Args: 163 rotate_worker_token (bool): Rotate the worker join token. Default: 164 ``False``. 165 rotate_manager_token (bool): Rotate the manager join token. 166 Default: ``False``. 167 rotate_manager_unlock_key (bool): Rotate the manager unlock key. 168 Default: ``False``. 169 Raises: 170 :py:class:`docker.errors.APIError` 171 If the server returns an error. 172 173 """ 174 # this seems to have to be set 175 if kwargs.get('node_cert_expiry') is None: 176 kwargs['node_cert_expiry'] = 7776000000000000 177 178 return self.client.api.update_swarm( 179 version=self.version, 180 swarm_spec=self.client.api.create_swarm_spec(**kwargs), 181 rotate_worker_token=rotate_worker_token, 182 rotate_manager_token=rotate_manager_token, 183 rotate_manager_unlock_key=rotate_manager_unlock_key 184 ) 185