unitlab 2.3.38__tar.gz → 2.3.40__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unitlab
3
- Version: 2.3.38
3
+ Version: 2.3.40
4
4
  Home-page: https://github.com/teamunitlab/unitlab-sdk
5
5
  Author: Unitlab Inc.
6
6
  Author-email: team@unitlab.ai
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
2
2
 
3
3
  setup(
4
4
  name="unitlab",
5
- version="2.3.38",
5
+ version="2.3.40",
6
6
  license="MIT",
7
7
  author="Unitlab Inc.",
8
8
  author_email="team@unitlab.ai",
@@ -56,24 +56,7 @@ class PersistentTunnel:
56
56
  self.jupyter_process = None
57
57
  self.tunnel_process = None
58
58
 
59
- def get_zone_id(self):
60
- """Get Zone ID for unitlab-ai.com"""
61
- print("🔍 Getting Zone ID for {}...".format(self.domain))
62
-
63
- url = "https://api.cloudflare.com/client/v4/zones"
64
- headers = self._get_headers()
65
- params = {"name": self.domain}
66
-
67
- response = requests.get(url, headers=headers, params=params)
68
- if response.status_code == 200:
69
- data = response.json()
70
- if data["result"]:
71
- self.cf_zone_id = data["result"][0]["id"]
72
- print("✅ Zone ID: {}".format(self.cf_zone_id))
73
- return self.cf_zone_id
74
-
75
- print("❌ Could not get Zone ID")
76
- return None
59
+
77
60
 
78
61
  def _get_headers(self):
79
62
  """Get API headers for Global API Key"""
@@ -85,32 +68,14 @@ class PersistentTunnel:
85
68
  }
86
69
 
87
70
  def get_or_create_tunnel(self):
88
- """Get existing tunnel or create a new one"""
89
- # First, check if tunnel already exists
90
- print("🔍 Checking for existing tunnel: {}...".format(self.tunnel_name))
91
-
92
- list_url = "https://api.cloudflare.com/client/v4/accounts/{}/cfd_tunnel".format(self.cf_account_id)
93
- headers = self._get_headers()
94
-
95
- # Check if tunnel exists
96
- response = requests.get(list_url, headers=headers)
97
- if response.status_code == 200:
98
- tunnels = response.json().get("result", [])
99
- for tunnel in tunnels:
100
- if tunnel["name"] == self.tunnel_name:
101
- print("✅ Found existing tunnel: {}".format(tunnel["id"]))
102
- self.tunnel_id = tunnel["id"]
103
-
104
- # Tunnel exists, create a new one with unique name
105
- print("⚠️ Tunnel with this name already exists")
106
- import uuid
107
- unique_suffix = str(uuid.uuid4())[:8]
108
- self.tunnel_name = "agent-{}-{}".format(self.device_id, unique_suffix)
109
- print("🔄 Creating new tunnel with unique name: {}".format(self.tunnel_name))
110
- # Don't break, let it continue to create new tunnel
111
- return self.create_new_tunnel()
112
-
113
- # Create new tunnel
71
+ """Always create a new tunnel with unique name to avoid conflicts"""
72
+ # Generate unique tunnel name to avoid conflicts
73
+ import uuid
74
+ unique_suffix = str(uuid.uuid4())[:8]
75
+ self.tunnel_name = "agent-{}-{}".format(self.device_id, unique_suffix)
76
+ print("🔧 Creating tunnel: {}...".format(self.tunnel_name))
77
+
78
+ # Always create new tunnel
114
79
  return self.create_new_tunnel()
115
80
 
116
81
  def create_new_tunnel(self):
@@ -160,9 +125,7 @@ class PersistentTunnel:
160
125
 
161
126
  print("🔧 Creating DNS records...")
162
127
 
163
- # Get zone ID if we don't have it
164
- if self.cf_zone_id == "NEED_ZONE_ID_FOR_1SCAN_UZ":
165
- self.get_zone_id()
128
+ # self.get_zone_id()
166
129
 
167
130
  url = "https://api.cloudflare.com/client/v4/zones/{}/dns_records".format(self.cf_zone_id)
168
131
  headers = self._get_headers()
@@ -186,7 +149,32 @@ class PersistentTunnel:
186
149
  print("❌ Failed to create main DNS: {}".format(response.text[:200]))
187
150
  return False
188
151
 
189
- # Create SSH subdomain record (s{deviceid}.unitlab-ai.com)
152
+ # First, check if SSH DNS record exists and delete it
153
+ print("🔍 Checking for existing SSH DNS record: {}.{}".format(self.ssh_subdomain, self.domain))
154
+ list_url = "{}?name={}.{}".format(url, self.ssh_subdomain, self.domain)
155
+ list_response = requests.get(list_url, headers=headers)
156
+
157
+ if list_response.status_code == 200:
158
+ records = list_response.json().get("result", [])
159
+ print("Found {} existing DNS records".format(len(records)))
160
+ print('this is new version')
161
+ for record in records:
162
+ if record["name"] == "{}.{}".format(self.ssh_subdomain, self.domain):
163
+ record_id = record["id"]
164
+ print("🗑️ Deleting old SSH DNS record: {}".format(record_id))
165
+ delete_url = "{}/{}".format(url, record_id)
166
+ delete_response = requests.delete(delete_url, headers=headers)
167
+ if delete_response.status_code in [200, 204]:
168
+ print("✅ Deleted old SSH DNS record")
169
+ else:
170
+ print("⚠️ Could not delete old SSH DNS record: {}".format(delete_response.text[:200]))
171
+ else:
172
+ print("⚠️ Could not list DNS records: {}".format(list_response.text[:200]))
173
+
174
+ # Wait a moment for DNS deletion to propagate
175
+ time.sleep(2)
176
+
177
+ # Create new SSH subdomain record pointing to new tunnel
190
178
  ssh_data = {
191
179
  "type": "CNAME",
192
180
  "name": self.ssh_subdomain,
@@ -195,31 +183,22 @@ class PersistentTunnel:
195
183
  "ttl": 1
196
184
  }
197
185
 
186
+ print("📝 Creating SSH DNS record: {} -> {}".format(self.ssh_subdomain, self.tunnel_id))
198
187
  ssh_response = requests.post(url, headers=headers, json=ssh_data)
199
188
 
200
189
  if ssh_response.status_code in [200, 201]:
201
190
  print("✅ SSH DNS record created: {}.{}".format(self.ssh_subdomain, self.domain))
202
- elif "already exists" in ssh_response.text:
203
- print("⚠️ SSH DNS record already exists, deleting and recreating...")
204
- # Delete the old record and create new one
205
- list_url = "{}?name={}.{}".format(url, self.ssh_subdomain, self.domain)
206
- list_response = requests.get(list_url, headers=headers)
207
- if list_response.status_code == 200:
208
- records = list_response.json().get("result", [])
209
- if records:
210
- record_id = records[0]["id"]
211
- delete_url = "{}/{}".format(url, record_id)
212
- requests.delete(delete_url, headers=headers)
213
- print("Deleted old SSH DNS record")
214
- # Try again
215
- ssh_response = requests.post(url, headers=headers, json=ssh_data)
216
- if ssh_response.status_code in [200, 201]:
217
- print("✅ SSH DNS record recreated: {}.{}".format(self.ssh_subdomain, self.domain))
218
- else:
219
- print("❌ Failed to recreate SSH DNS: {}".format(ssh_response.text[:200]))
191
+ print(" Points to: {}.cfargotunnel.com".format(self.tunnel_id))
220
192
  else:
221
- print("❌ Could not create SSH DNS: {}".format(ssh_response.text[:200]))
222
- # SSH is optional, so we continue even if SSH DNS fails
193
+ print("❌ Failed to create SSH DNS: Status {} - {}".format(ssh_response.status_code, ssh_response.text))
194
+ # Try to parse error
195
+ try:
196
+ error_data = ssh_response.json()
197
+ if "errors" in error_data:
198
+ for error in error_data["errors"]:
199
+ print(" Error: {}".format(error.get("message", error)))
200
+ except:
201
+ pass
223
202
 
224
203
  return True
225
204
 
@@ -261,6 +240,7 @@ class PersistentTunnel:
261
240
 
262
241
  policy_response = requests.post(policy_url, headers=headers, json=policy_data)
263
242
 
243
+
264
244
  if policy_response.status_code in [200, 201]:
265
245
  print("✅ Bypass policy created - SSH is publicly accessible")
266
246
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unitlab
3
- Version: 2.3.38
3
+ Version: 2.3.40
4
4
  Home-page: https://github.com/teamunitlab/unitlab-sdk
5
5
  Author: Unitlab Inc.
6
6
  Author-email: team@unitlab.ai
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes