Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update examples.md with logout in Python #217

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 101 additions & 3 deletions docs/api/central/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ In the examples below use the following placeholder variables to match commonly-
- `$ZT_TOKEN`: an API token associated with an active account on [Central](https://my.zerotier.com)
- `$NWID`: an active network ID

Please note, if you encounter an error, System.String and System.Collections.IDictionary when using curl within Powershell, be advised this is because of an _alias_ which can leads to a less than obvious error message. `curl` in PowerShell is a wrapper for `Invoke-WebRequest` which has different parameter syntax than `curl` on non-windows operating systems. As an alternative solution to using `Invoke-WebRequest`, `curl.exe` could be used. This however may not be available on your system without first installing. The _native_ approach is to use `Invoke-WebRequest`. Caveat emptor.
Please note, if you encounter an error, System.String and System.Collections.IDictionary when using curl within Powershell, be advised this is because of an _alias_ which lead to a less than obvious error message. `curl` in PowerShell is a wrapper for `Invoke-WebRequest` which has different parameter syntax than `curl` on non-windows operating systems. As an alternative solution to using `Invoke-WebRequest`, use `curl.exe`. This however may not be available on your system without first installing. The _native_ approach on Microsoft Windows is to use `Invoke-WebRequest`. Caveat emptor.

:::info
See the [Central API Tokens](/api/tokens) guide for an explanation of how to create and manage API tokens.
Expand All @@ -31,7 +31,7 @@ Each of them will fetch network information and produce CSV as output. You can t
defaultValue="list-networks"
values={[
{label: 'Networks', value: 'list-networks'},
{label: 'Network Members', value: 'list-members'}
{label: 'Network Members', value: 'list-members'},
]}>

<TabItem value="list-networks">
Expand Down Expand Up @@ -140,7 +140,8 @@ If you want to save the output to a file, you can add `| Out-File -FilePath "out
defaultValue="authorize-member"
values={[
{label: 'Authorize Member', value: 'authorize-member'},
{label: 'Deauthorize Member', value: 'deauthorize-member'}
{label: 'Deauthorize Member', value: 'deauthorize-member'},
{label: 'Clean up a node', value: 'clean-up-a-node'}
]}>

<TabItem value="authorize-member">
Expand Down Expand Up @@ -186,6 +187,8 @@ curl -H "Authorization: token $ZT_TOKEN" -X POST \
--data '{"config": {"authorized": false}}'
```

In addition to notifying Central with this API call, and in order to not require waiting until the current credentials expire, the ZeroTierOne service needs to be stopped and the authtoken.secret needs to be removed. The API call in addition to the removal of the local secret file prevents incremental billing to increase unbounded in cases of repeat auth/deauth use cases. Also note, the deauthorize is required per individual network within an organization the node is present.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, authtoken.secret plays no role in this at all.

### Deauthorize a network member ( Powershell Invoke-WebRequest )

```code
Expand All @@ -207,6 +210,101 @@ Invoke-WebRequest -Uri "https://api.zerotier.com/api/v1/network/$NWID/member/$ME
-Method Post -Headers $headers -Body $body -ContentType "application/json"
```

In addition to notifying Central with this API call, and in order to not require waiting until the current credentials expire, the ZeroTierOne service needs to be stopped and the authtoken.secret needs to be removed. The API call in addition to the removal of the local secret file prevents incremental billing to increase unbounded in cases of repeat auth/deauth use cases. Also note, the deauthorize is required per individual network within an organization the node is present.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

authtoken.secret has absolutely nothing to do with any of this. authtoken.secret is the API token to access the REST API of the local service.


</TabItem>

<TabItem value="clean-up-a-node">

### Cleanup a node ( Python )

```code
import os
import requests
import subprocess
import time
import sys

def cleanup_zerotier_node(api_token, node_id, network_ids):
"""
Comprehensive cleanup of a ZeroTier node:
1. Deauthorize from each network
2. Stop ZeroTier service
3. Remove auth token
4. Restart ZeroTier service
"""
# Base URL for ZeroTier Central API
base_url = "https://api.zerotier.com/api/v1"
headers = {
"Authorization": f"Bearer {api_token}"
}

# 1. Deauthorize from each network
for network_id in network_ids:
url = f"{base_url}/network/{network_id}/member/{node_id}"
try:
requests.delete(url, headers=headers)
print(f"Deauthorized from network {network_id}")
except Exception as e:
print(f"Error deauthorizing from network {network_id}: {e}")

# 2. Stop ZeroTier service
try:
if os.name == 'nt': # Windows
subprocess.run(['net', 'stop', 'ZeroTierOne'], check=True)
else: # Linux/MacOS
subprocess.run(['sudo', 'systemctl', 'stop', 'zerotier-one'], check=True)
print("ZeroTier service stopped")
except Exception as e:
print(f"Error stopping ZeroTier service: {e}")

# 3. Remove authtoken.secret
try:
if os.name == 'nt':
token_path = r'C:\ProgramData\ZeroTier\One\authtoken.secret'
else:
token_path = '/var/lib/zerotier-one/authtoken.secret'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you removing authtoken.secret?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to effect an immediate logout on a device used by more than one SSO login.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleting authtoken.secret doesn't do that. There's nothing you can do from the client side to do that.


if os.path.exists(token_path):
os.remove(token_path)
print("Removed authtoken.secret")
except Exception as e:
print(f"Error removing authtoken.secret: {e}")

# 4. Restart ZeroTier service
try:
time.sleep(2) # Brief pause before restart
if os.name == 'nt': # Windows
subprocess.run(['net', 'start', 'ZeroTierOne'], check=True)
else: # Linux/MacOS
subprocess.run(['sudo', 'systemctl', 'start', 'zerotier-one'], check=True)
print("ZeroTier service restarted")
except Exception as e:
print(f"Error restarting ZeroTier service: {e}")

# Example usage
if __name__ == "__main__":
# Read required environment variables
API_TOKEN = os.getenv('ZEROTIER_API_TOKEN')
NODE_ID = os.getenv('ZEROTIER_NODE_ID')

# Validate environment variables
if not API_TOKEN:
print("Error: ZEROTIER_API_TOKEN environment variable is not set")
sys.exit(1)
if not NODE_ID:
print("Error: ZEROTIER_NODE_ID environment variable is not set")
sys.exit(1)

# Network IDs can be passed as command line arguments
NETWORK_IDS = sys.argv[1:] if len(sys.argv) > 1 else []
if not NETWORK_IDS:
print("Warning: No network IDs provided. Please provide network IDs as command line arguments.")
sys.exit(1)

cleanup_zerotier_node(API_TOKEN, NODE_ID, NETWORK_IDS)
```

</TabItem>

</Tabs>