Module jumpscale.clients.zerotier.zerotier
A client that gives an interface to the zerotier api
zcl = j.clients.zerotier.get("instance")
network = zcl.get_network("network_id")
#  list routes
network.routes
# add members
member = network.add_member(address, name="guest")
# Authorize member to this network
member.authorize()
Expand source code
"""
A client that gives an interface to the zerotier api
```python
zcl = j.clients.zerotier.get("instance")
network = zcl.get_network("network_id")
#  list routes
network.routes
# add members
member = network.add_member(address, name="guest")
# Authorize member to this network
member.authorize()
```
"""
import requests
import ipaddress
from jumpscale.loader import j
from jumpscale.clients.base import Client
from jumpscale.core.base import fields
class Member:
    def __init__(self, member_data, network, address=None):
        self.raw_data = member_data
        self._address = address
        self._network = network
        self.id = member_data["id"]
    @property
    def address(self):
        if not self._address:
            self._address = self.identity.split(":")[0]
        return self._address
    @property
    def identity(self):
        return self.raw_data["config"]["identity"]
    @property
    def private_ip(self):
        return self.raw_data["config"]["ipAssignments"]
    def _update_authorization(self, authorize):
        if self.raw_data["config"]["authorized"] == authorize:
            return
        self._network.update_member(self.address, authorized=authorize)
        self.raw_data["config"]["authorized"] = authorize
    def authorize(self):
        """Authorize member to the zerotier network
        """
        self._update_authorization(True)
    def unauthorize(self):
        """Unauthorize member to the zerotier network
        """
        self._update_authorization(False)
    def __repr__(self):
        return f"Member({self.id})"
class Network:
    def __init__(self, network_data, client):
        self.id = network_data["id"]
        self._client = client
        self.raw_data = network_data
    @property
    def name(self):
        return self.raw_data["config"]["name"]
    @property
    def routes(self):
        return self.raw_data["config"]["routes"]
    def list_members(self):
        """List all members of  that network
        Returns:
            list: List of all members
        """
        return [Member(member, self) for member in self._client._send_request(f"network/{self.id}/member")]
    def add_member(self, address, name=None, private_ip=None, authorized=True):
        """Add a member to the network
        Args:
            address (str): Address of the member
            name (str, optional): Name of the member. Defaults to None.
            private_ip (str, optional): Private IP to assign. Defaults to None.
            authorized (bool, optional): Whether to authorize the user or not. Defaults to True.
        Returns:
            Member: Added member
        """
        data = {"config": {"authorized": authorized}, "name": name}
        if private_ip:
            data["config"]["ipAssignments"] = [private_ip]
        member_data = self._client._send_request(f"network/{self.id}/member/{address}", method="post", data=data)
        return Member(member_data, self, address)
    def update_member(self, address, name=None, private_ip=None, authorized=None):
        """Update a member in the network
        Args:
            address (str): Address of the member
            name (str, optional): Name of the member. Defaults to None.
            private_ip (str, optional): Private IP to assign. Defaults to None.
            authorized (bool, optional): Whether to authorize the user or not. Defaults to True.
        Returns:
            Member: Added member
        """
        return self.add_member(address, name, private_ip, authorized)
    def get_member(self, address):
        """Returns member by address
        Args:
            address (str): Member address
        Returns:
            Member: Found member
        """
        return Member(self._client._send_request(f"network/{self.id}/member/{address}"), self, address)
    def delete_member(self, address):
        """Deletes a member
        Args:
            address (str): Member address
        """
        self._client._send_request(f"network/{self.id}/member/{address}", method="delete", return_json=False)
    def __repr__(self):
        return f"Network({self.id})"
class ZerotierClient(Client):
    base_url = fields.String(default="https://my.zerotier.com/api")
    token = fields.String()
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._session = None
    def _send_request(self, path, method="get", data=None, return_json=True):
        url = f"{self.base_url}/{path}"
        func_method = getattr(self.session, method)
        res = func_method(url, json=data)
        res.raise_for_status()
        if return_json:
            return res.json()
        else:
            return res.content
    @property
    def session(self):
        if not self._session:
            if not self.token:
                raise j.exceptions.Value("Please set token to use the client")
            self._session = requests.Session()
            self._session.headers["Authorization"] = f"Bearer {self.token}"
        return self._session
    def list_networks(self):
        """List networks available to user
        Returns:
            list: All available networks
        """
        return [Network(network, self) for network in self._send_request("network")]
    def get_network(self, network_id):
        """Get network by id
        Args:
            network_id (str): Network id
        Returns:
            Network: Found network
        """
        return Network(self._send_request(f"network/{network_id}"), self)
    def create_network(self, public, target_subnet=None, name=None, auto_assign=True):
        """Create a new network
        Args:
            public (bool): Specify if network is public or not
            target_subnet (str, optional): Target network to be pick assignment ips from. Defaults to None.
            name (str, optional): Name of the network. Defaults to None.
            auto_assign (bool, optional): If true auto assign addresses. Defaults to True.
        Returns:
            Network: Created network
        """
        routes = None
        config = {"private": not public, "noAutoAssignIps": not auto_assign, "routes": routes}
        if target_subnet:
            routes.append({"target": target_subnet, "via": None})
            network = ipaddress.IPv4Network(target_subnet)
            config["ipAssignmentPools"] = [{"ipRangeStart": network[0], "ipRangeEnd": network[-1]}]
        if name:
            config.update({"name": name})
        data = {"config": config}
        return Network(self._send_request(f"network", data=data, method="post"), self)
    def delete_network(self, network_id):
        """Deletes network
        Args:
            network_id (str): Network id
        """
        self._send_request(f"network/{network_id}", method="delete", return_json=False)
    def get_status(self):
        return self._send_request("status")
Classes
class Member (member_data, network, address=None)- 
Expand source code
class Member: def __init__(self, member_data, network, address=None): self.raw_data = member_data self._address = address self._network = network self.id = member_data["id"] @property def address(self): if not self._address: self._address = self.identity.split(":")[0] return self._address @property def identity(self): return self.raw_data["config"]["identity"] @property def private_ip(self): return self.raw_data["config"]["ipAssignments"] def _update_authorization(self, authorize): if self.raw_data["config"]["authorized"] == authorize: return self._network.update_member(self.address, authorized=authorize) self.raw_data["config"]["authorized"] = authorize def authorize(self): """Authorize member to the zerotier network """ self._update_authorization(True) def unauthorize(self): """Unauthorize member to the zerotier network """ self._update_authorization(False) def __repr__(self): return f"Member({self.id})"Instance variables
var address- 
Expand source code
@property def address(self): if not self._address: self._address = self.identity.split(":")[0] return self._address var identity- 
Expand source code
@property def identity(self): return self.raw_data["config"]["identity"] var private_ip- 
Expand source code
@property def private_ip(self): return self.raw_data["config"]["ipAssignments"] 
Methods
- 
Authorize member to the zerotier network
Expand source code
def authorize(self): """Authorize member to the zerotier network """ self._update_authorization(True) - 
Unauthorize member to the zerotier network
Expand source code
def unauthorize(self): """Unauthorize member to the zerotier network """ self._update_authorization(False) 
 class Network (network_data, client)- 
Expand source code
class Network: def __init__(self, network_data, client): self.id = network_data["id"] self._client = client self.raw_data = network_data @property def name(self): return self.raw_data["config"]["name"] @property def routes(self): return self.raw_data["config"]["routes"] def list_members(self): """List all members of that network Returns: list: List of all members """ return [Member(member, self) for member in self._client._send_request(f"network/{self.id}/member")] def add_member(self, address, name=None, private_ip=None, authorized=True): """Add a member to the network Args: address (str): Address of the member name (str, optional): Name of the member. Defaults to None. private_ip (str, optional): Private IP to assign. Defaults to None. authorized (bool, optional): Whether to authorize the user or not. Defaults to True. Returns: Member: Added member """ data = {"config": {"authorized": authorized}, "name": name} if private_ip: data["config"]["ipAssignments"] = [private_ip] member_data = self._client._send_request(f"network/{self.id}/member/{address}", method="post", data=data) return Member(member_data, self, address) def update_member(self, address, name=None, private_ip=None, authorized=None): """Update a member in the network Args: address (str): Address of the member name (str, optional): Name of the member. Defaults to None. private_ip (str, optional): Private IP to assign. Defaults to None. authorized (bool, optional): Whether to authorize the user or not. Defaults to True. Returns: Member: Added member """ return self.add_member(address, name, private_ip, authorized) def get_member(self, address): """Returns member by address Args: address (str): Member address Returns: Member: Found member """ return Member(self._client._send_request(f"network/{self.id}/member/{address}"), self, address) def delete_member(self, address): """Deletes a member Args: address (str): Member address """ self._client._send_request(f"network/{self.id}/member/{address}", method="delete", return_json=False) def __repr__(self): return f"Network({self.id})"Instance variables
var name- 
Expand source code
@property def name(self): return self.raw_data["config"]["name"] var routes- 
Expand source code
@property def routes(self): return self.raw_data["config"]["routes"] 
Methods
def add_member(self, address, name=None, private_ip=None, authorized=True)- 
Add a member to the network
Args
address:str- Address of the member
 name:str, optional- Name of the member. Defaults to None.
 private_ip:str, optional- Private IP to assign. Defaults to None.
 authorized:bool, optional- Whether to authorize the user or not. Defaults to True.
 
Returns
Member- Added member
 
Expand source code
def add_member(self, address, name=None, private_ip=None, authorized=True): """Add a member to the network Args: address (str): Address of the member name (str, optional): Name of the member. Defaults to None. private_ip (str, optional): Private IP to assign. Defaults to None. authorized (bool, optional): Whether to authorize the user or not. Defaults to True. Returns: Member: Added member """ data = {"config": {"authorized": authorized}, "name": name} if private_ip: data["config"]["ipAssignments"] = [private_ip] member_data = self._client._send_request(f"network/{self.id}/member/{address}", method="post", data=data) return Member(member_data, self, address) def delete_member(self, address)- 
Deletes a member
Args
address:str- Member address
 
Expand source code
def delete_member(self, address): """Deletes a member Args: address (str): Member address """ self._client._send_request(f"network/{self.id}/member/{address}", method="delete", return_json=False) def get_member(self, address)- 
Expand source code
def get_member(self, address): """Returns member by address Args: address (str): Member address Returns: Member: Found member """ return Member(self._client._send_request(f"network/{self.id}/member/{address}"), self, address) def list_members(self)- 
List all members of that network
Returns
list- List of all members
 
Expand source code
def list_members(self): """List all members of that network Returns: list: List of all members """ return [Member(member, self) for member in self._client._send_request(f"network/{self.id}/member")] def update_member(self, address, name=None, private_ip=None, authorized=None)- 
Update a member in the network
Args
address:str- Address of the member
 name:str, optional- Name of the member. Defaults to None.
 private_ip:str, optional- Private IP to assign. Defaults to None.
 authorized:bool, optional- Whether to authorize the user or not. Defaults to True.
 
Returns
Member- Added member
 
Expand source code
def update_member(self, address, name=None, private_ip=None, authorized=None): """Update a member in the network Args: address (str): Address of the member name (str, optional): Name of the member. Defaults to None. private_ip (str, optional): Private IP to assign. Defaults to None. authorized (bool, optional): Whether to authorize the user or not. Defaults to True. Returns: Member: Added member """ return self.add_member(address, name, private_ip, authorized) 
 class ZerotierClient (*args, **kwargs)- 
A simple attribute-based namespace.
SimpleNamespace(**kwargs)
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
any instance can have an optional name and a parent.
class Person(Base): name = fields.String() age = fields.Float() p = Person(name="ahmed", age="19") print(p.name, p.age)Args
parent_:Base, optional- parent instance. Defaults to None.
 instance_name_:str, optional- instance name. Defaults to None.
 **values- any given field values to initiate the instance with
 
Expand source code
class ZerotierClient(Client): base_url = fields.String(default="https://my.zerotier.com/api") token = fields.String() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._session = None def _send_request(self, path, method="get", data=None, return_json=True): url = f"{self.base_url}/{path}" func_method = getattr(self.session, method) res = func_method(url, json=data) res.raise_for_status() if return_json: return res.json() else: return res.content @property def session(self): if not self._session: if not self.token: raise j.exceptions.Value("Please set token to use the client") self._session = requests.Session() self._session.headers["Authorization"] = f"Bearer {self.token}" return self._session def list_networks(self): """List networks available to user Returns: list: All available networks """ return [Network(network, self) for network in self._send_request("network")] def get_network(self, network_id): """Get network by id Args: network_id (str): Network id Returns: Network: Found network """ return Network(self._send_request(f"network/{network_id}"), self) def create_network(self, public, target_subnet=None, name=None, auto_assign=True): """Create a new network Args: public (bool): Specify if network is public or not target_subnet (str, optional): Target network to be pick assignment ips from. Defaults to None. name (str, optional): Name of the network. Defaults to None. auto_assign (bool, optional): If true auto assign addresses. Defaults to True. Returns: Network: Created network """ routes = None config = {"private": not public, "noAutoAssignIps": not auto_assign, "routes": routes} if target_subnet: routes.append({"target": target_subnet, "via": None}) network = ipaddress.IPv4Network(target_subnet) config["ipAssignmentPools"] = [{"ipRangeStart": network[0], "ipRangeEnd": network[-1]}] if name: config.update({"name": name}) data = {"config": config} return Network(self._send_request(f"network", data=data, method="post"), self) def delete_network(self, network_id): """Deletes network Args: network_id (str): Network id """ self._send_request(f"network/{network_id}", method="delete", return_json=False) def get_status(self): return self._send_request("status")Ancestors
Instance variables
var base_url- 
getter method this property
will call
_get_value, which would if the value is already defined and will get the default value if notReturns
any- the field value
 
Expand source code
def getter(self): """ getter method this property will call `_get_value`, which would if the value is already defined and will get the default value if not Returns: any: the field value """ return self._get_value(name, field) var session- 
Expand source code
@property def session(self): if not self._session: if not self.token: raise j.exceptions.Value("Please set token to use the client") self._session = requests.Session() self._session.headers["Authorization"] = f"Bearer {self.token}" return self._session var token- 
getter method this property
will call
_get_value, which would if the value is already defined and will get the default value if notReturns
any- the field value
 
Expand source code
def getter(self): """ getter method this property will call `_get_value`, which would if the value is already defined and will get the default value if not Returns: any: the field value """ return self._get_value(name, field) 
Methods
def create_network(self, public, target_subnet=None, name=None, auto_assign=True)- 
Create a new network
Args
public:bool- Specify if network is public or not
 target_subnet:str, optional- Target network to be pick assignment ips from. Defaults to None.
 name:str, optional- Name of the network. Defaults to None.
 auto_assign:bool, optional- If true auto assign addresses. Defaults to True.
 
Returns
Network- Created network
 
Expand source code
def create_network(self, public, target_subnet=None, name=None, auto_assign=True): """Create a new network Args: public (bool): Specify if network is public or not target_subnet (str, optional): Target network to be pick assignment ips from. Defaults to None. name (str, optional): Name of the network. Defaults to None. auto_assign (bool, optional): If true auto assign addresses. Defaults to True. Returns: Network: Created network """ routes = None config = {"private": not public, "noAutoAssignIps": not auto_assign, "routes": routes} if target_subnet: routes.append({"target": target_subnet, "via": None}) network = ipaddress.IPv4Network(target_subnet) config["ipAssignmentPools"] = [{"ipRangeStart": network[0], "ipRangeEnd": network[-1]}] if name: config.update({"name": name}) data = {"config": config} return Network(self._send_request(f"network", data=data, method="post"), self) def delete_network(self, network_id)- 
Deletes network
Args
network_id:str- Network id
 
Expand source code
def delete_network(self, network_id): """Deletes network Args: network_id (str): Network id """ self._send_request(f"network/{network_id}", method="delete", return_json=False) def get_network(self, network_id)- 
Expand source code
def get_network(self, network_id): """Get network by id Args: network_id (str): Network id Returns: Network: Found network """ return Network(self._send_request(f"network/{network_id}"), self) def get_status(self)- 
Expand source code
def get_status(self): return self._send_request("status") def list_networks(self)- 
List networks available to user
Returns
list- All available networks
 
Expand source code
def list_networks(self): """List networks available to user Returns: list: All available networks """ return [Network(network, self) for network in self._send_request("network")] 
Inherited members