2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-11 12:06:26 +00:00
Files
confluent/confluent_osdeploy/common/initramfs/opt/confluent/bin/apiclient
T
Markus Hilger 644843b892 Remove unused imports and pointless f-string prefixes (F401, F541, E713)
Entirely mechanical, produced by `ruff check --fix --select F401,F541,E713`
and reviewed rather than taken on faith: deleting an import is only safe if
nothing imports it for its side effects or re-exports it.  None of the 19
removed names is referenced anywhere in its file, none appears in any string
literal, and none of the touched files uses eval, exec, globals() or
__import__, so there is no dynamic lookup that could reach them.
2026-08-10 05:32:00 +02:00

726 lines
27 KiB
Python

#!/usr/bin/python
try:
import http.client as client
except ImportError:
import httplib as client
import base64
import ctypes
import ctypes.util
import os
import select
import socket
import subprocess
import ssl
import sys
import time
import re
import hashlib
try:
import json
import hmac
except ImportError:
json = None
hmac = None
# Ignore proxy-based environment variables
for proxy_var in ['http_proxy', 'https_proxy', 'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'all_proxy', 'NO_PROXY', 'no_proxy']:
os.environ.pop(proxy_var, None)
class InvalidApiKey(Exception):
pass
def msg_align(len):
return (len + 3) & ~3
try:
_protoparm = ssl.PROTOCOL_TLS_CLIENT
except AttributeError:
_protoparm = ssl.PROTOCOL_SSLv23
cryptname = ctypes.util.find_library('crypt')
if not cryptname:
if os.path.exists('/lib64/libcrypt.so.2') or os.path.exists('/usr/lib64/libcrypt.so.2'):
cryptname = 'libcrypt.so.2'
else:
cryptname = 'libcrypt.so.1'
c_libcrypt = ctypes.CDLL(cryptname)
c_crypt = c_libcrypt.crypt
c_crypt.argtypes = (ctypes.c_char_p, ctypes.c_char_p)
c_crypt.restype = ctypes.c_char_p
def get_my_addresses():
addrs = []
for ifa in get_ifaddrs():
if ifa[0] == 'ip':
addrs.append((ifa[1], ifa[2], ifa[3]))
return addrs
def get_mac_addresses():
macs = []
for ifa in get_ifaddrs():
if ifa[0] == 'ETHER':
macs.append((ifa[1], ifa[2]))
return macs
def get_ifaddrs():
class sockaddr(ctypes.Structure):
_fields_ = [
('sa_family', ctypes.c_uint16),
('sa_data', ctypes.c_ubyte * 14),
]
class sockaddr_in(ctypes.Structure):
_fields_ = [
('sin_family', ctypes.c_uint16),
('sin_port', ctypes.c_uint16),
('sin_addr', ctypes.c_ubyte * 4),
('sin_zero', ctypes.c_ubyte * 8),
]
class sockaddr_in6(ctypes.Structure):
_fields_ = [
('sin6_family', ctypes.c_uint16),
('sin6_port', ctypes.c_uint16),
('sin6_flowinfo', ctypes.c_uint32),
('sin6_addr', ctypes.c_ubyte * 16),
('sin6_scope_id', ctypes.c_uint32),
]
class sockaddr_ll(ctypes.Structure):
_fields_ = [
('sll_family', ctypes.c_uint16),
('sll_protocol', ctypes.c_uint16),
('sll_ifindex', ctypes.c_int32),
('sll_hatype', ctypes.c_uint16),
('sll_pkttype', ctypes.c_uint8),
('sll_halen', ctypes.c_uint8),
('sll_addr', ctypes.c_ubyte * 8),
]
class ifaddrs(ctypes.Structure):
pass
ifaddrs._fields_ = [
('ifa_next', ctypes.POINTER(ifaddrs)),
('ifa_name', ctypes.c_char_p),
('ifa_flags', ctypes.c_uint),
('ifa_addr', ctypes.POINTER(sockaddr)),
('ifa_netmask', ctypes.POINTER(sockaddr)),
('ifa_ifu', ctypes.POINTER(sockaddr)),
('ifa_data', ctypes.c_void_p),
]
libc = ctypes.CDLL(ctypes.util.find_library('c'))
libc.getifaddrs.argtypes = [ctypes.POINTER(ctypes.POINTER(ifaddrs))]
libc.getifaddrs.restype = ctypes.c_int
libc.freeifaddrs.argtypes = [ctypes.POINTER(ifaddrs)]
libc.freeifaddrs.restype = None
ifap = ctypes.POINTER(ifaddrs)()
result = libc.getifaddrs(ctypes.pointer(ifap))
if result != 0:
return []
addresses = []
ifa = ifap
try:
while ifa:
if ifa.contents.ifa_addr:
family = ifa.contents.ifa_addr.contents.sa_family
name = ifa.contents.ifa_name.decode('utf-8') if ifa.contents.ifa_name else None
if family in (socket.AF_INET, socket.AF_INET6):
# skip loopback and non-multicast interfaces
if ifa.contents.ifa_flags & 8 or not ifa.contents.ifa_flags & 0x1000:
ifa = ifa.contents.ifa_next
continue
if family == socket.AF_INET:
addr_ptr = ctypes.cast(ifa.contents.ifa_addr, ctypes.POINTER(sockaddr_in))
addr_bytes = bytes(addr_ptr.contents.sin_addr)
if_index = socket.if_nametoindex(name) if name else 0
addresses.append(('ip', family, addr_bytes, if_index))
elif family == socket.AF_INET6:
addr_ptr = ctypes.cast(ifa.contents.ifa_addr, ctypes.POINTER(sockaddr_in6))
addr_bytes = bytes(addr_ptr.contents.sin6_addr)
scope_id = addr_ptr.contents.sin6_scope_id
addresses.append(('ip', family, addr_bytes, scope_id))
elif family == socket.AF_PACKET:
addr_ptr = ctypes.cast(ifa.contents.ifa_addr, ctypes.POINTER(sockaddr_ll))
halen = addr_ptr.contents.sll_halen
if addr_ptr.contents.sll_hatype in (1, 32) and halen > 0: # ARPHRD_ETHER or ARPHRD_INFINIBAND
if addr_ptr.contents.sll_hatype == 1 and addr_ptr.contents.sll_addr[0] & 2: # skip locally administered MACs
ifa = ifa.contents.ifa_next
continue
mac_bytes = bytes(addr_ptr.contents.sll_addr[:halen])
macaddr = ':'.join('{:02x}'.format(b) for b in mac_bytes)
addresses.append(('ETHER', name, macaddr))
ifa = ifa.contents.ifa_next
finally:
libc.freeifaddrs(ifap)
return addresses
def scan_confluents(confuuid=None):
srvs = {}
s6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
try:
s6.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except Exception:
# REUSPORT is ideal, but if python is missing it, just live with the limitation
pass
try: # We would like to bind for firewall rules, however if not possible then leave it alone
s6.bind(('::', 1900))
except Exception:
pass
s4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s4.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
try:
s4.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except Exception:
# REUSPORT is ideal, but if python is missing it, just live with the limitation
pass
try:
s4.bind(('0.0.0.0', 1900))
except Exception:
pass
doneidxs = set([])
msg = 'M-SEARCH * HTTP/1.1\r\nST: urn:xcat.org:service:confluent:'
if not confuuid and os.path.exists('/etc/confluent/confluent.deploycfg'):
with open('/etc/confluent/confluent.deploycfg') as dcfg:
for line in dcfg.read().split('\n'):
if line.startswith('confluent_uuid:'):
confluentuuid = line.split(': ')[1]
msg += '/confluentuuid=' + confluentuuid
break
if not confuuid and os.path.exists('/confluent_uuid'):
with open('/confluent_uuid') as cuuidin:
confluentuuid = cuuidin.read().strip()
msg += '/confluentuuid=' + confluentuuid
try:
with open('/sys/devices/virtual/dmi/id/product_uuid') as uuidin:
msg += '/uuid=' + uuidin.read().strip()
except Exception:
pass
for iface, hwaddr in get_mac_addresses():
msg += '/mac=' + hwaddr
msg = msg.encode('utf8')
for addr in get_my_addresses():
if addr[0] == socket.AF_INET6:
if addr[-1] in doneidxs:
continue
try:
s6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, addr[-1])
except TypeError:
s6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, addr[-1].tobytes())
try:
s6.sendto(msg, ('ff02::c', 1900))
except OSError:
pass
doneidxs.add(addr[-1])
elif addr[0] == socket.AF_INET:
try:
s4.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, addr[1])
except TypeError:
s4.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, addr[1].tobytes())
try:
s4.sendto(msg, ('239.255.255.250', 1900))
except OSError:
pass
r = select.select((s4, s6), (), (), 4)
srvlist = []
if r:
r = r[0]
nodename = None
while r:
for s in r:
(rsp, peer) = s.recvfrom(9000)
rsp = rsp.split(b'\r\n')
current = None
for line in rsp:
if line.startswith(b'NODENAME: '):
nodename = line.replace(b'NODENAME: ', b'').strip().decode('utf8')
current = {}
elif line.startswith(b'DEFAULTNET: 1'):
current['isdefault'] = True
elif line.startswith(b'MGTIFACE: '):
current['mgtiface'] = line.replace(b'MGTIFACE: ', b'').strip().decode('utf8')
if len(peer) > 2:
current['myidx'] = peer[-1]
currip = peer[0]
if currip.startswith('fe80::') and '%' not in currip:
currip = '{0}%{1}'.format(currip, peer[-1])
srvs[currip] = current
if currip not in srvlist:
srvlist.append(currip)
r = select.select((s4, s6), (), (), 2)
if r:
r = r[0]
if not os.path.exists('/etc/confluent/confluent.info'):
with open('/etc/confluent/confluent.info', 'w+') as cinfo:
if nodename:
cinfo.write('NODENAME: {0}\n'.format(nodename))
for srv in srvlist:
cinfo.write('MANAGER: {0}\n'.format(srv))
return srvlist, srvs
def get_net_apikey(nodename, mgr, hmackey=None, confuuid=None):
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./'
newpass = ''.join([alpha[x >> 2] for x in bytearray(os.urandom(32))])
salt = '$5$' + ''.join([alpha[x >> 2] for x in bytearray(os.urandom(8))])
newpass = newpass.encode('utf8')
salt = salt.encode('utf8')
crypted = c_crypt(newpass, salt)
if hmackey:
hmacvalue = hmac.new(hmackey.encode('utf8'), crypted, hashlib.sha256).digest()
hmacvalue = base64.b64encode(hmacvalue).decode('utf8')
client = HTTPSClient(host=mgr, phmac=hmacvalue, nodename=nodename, confuuid=confuuid)
try:
status, rsp = client.grab_url_with_status('/confluent-api/self/registerapikey', data=crypted, returnrsp=True)
if status == 200:
return newpass.decode('utf8')
except Exception:
pass
for addrinfo in socket.getaddrinfo(mgr, 13001, 0, socket.SOCK_STREAM):
try:
clisock = socket.socket(addrinfo[0], addrinfo[1])
clisock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if addrinfo[0] == socket.AF_INET:
cliaddr = ('0.0.0.0', 302)
else:
cliaddr = ('::', 302)
clisock.bind(cliaddr)
clisock.settimeout(1)
clisock.connect(addrinfo[-1])
rsp = clisock.recv(8)
if rsp != b'\xc2\xd1-\xa8\x80\xd8j\xba':
raise Exception('Unrecognized credential banner')
hellostr = bytearray([1, len(nodename)]) + bytearray(nodename.encode('utf8')) + bytearray(b'\x00\x00')
clisock.send(hellostr)
rsp = bytearray(clisock.recv(2))
if not rsp:
continue
if rsp[0] == 128:
continue
if rsp[0] == 2:
echotoken = clisock.recv(rsp[1])
clisock.recv(2) # drain \x00\x00
clisock.send(bytes(bytearray([3, rsp[1]])))
clisock.send(echotoken)
clisock.send(bytes(bytearray([4, len(crypted)])))
clisock.send(crypted)
clisock.send(b'\x00\x00')
rsp = bytearray(clisock.recv(2))
if rsp[0] == 5:
return newpass.decode('utf8')
finally:
clisock.close()
return ''
def get_apikey(nodename, hosts, errout=None, hmackey=None, confuuid=None):
apikey = ""
if os.path.exists('/etc/confluent/confluent.apikey'):
apikey = open('/etc/confluent/confluent.apikey').read().strip()
if apikey:
return apikey
while not apikey:
for host in hosts:
try:
apikey = get_net_apikey(nodename, host, hmackey=hmackey, confuuid=confuuid)
except OSError:
apikey = None
if apikey:
break
else:
srvlist, _ = scan_confluents(confuuid=confuuid)
for host in srvlist:
try:
apikey = get_net_apikey(nodename, host, hmackey=hmackey, confuuid=confuuid)
except OSError:
apikey = None
if apikey:
break
if not apikey:
errmsg = "Failed getting API token, check deployment.apiarmed attribute on {}\n".format(nodename)
sys.stderr.write(errmsg)
if errout:
errout.write(errmsg)
time.sleep(10)
with open('/etc/confluent/confluent.apikey', 'w+') as apiout:
apiout.write(apikey)
apikey = apikey.strip()
os.chmod('/etc/confluent/confluent.apikey', 0o600)
return apikey
class HTTPSClient(client.HTTPConnection, object):
def __init__(self, usejson=False, port=443, host=None, errout=None, phmac=None, checkonly=False, hmackey=None, nodename=None, confuuid=None):
self.ignorehosts = set([])
self.phmac = phmac
self.hmackey = hmackey
self.confuuid = confuuid
self.errout = None
self.stdheaders = {}
if nodename:
self.stdheaders['CONFLUENT_NODENAME'] = nodename
if errout:
self.errout = open(errout, 'w')
self.errout.flush()
mgtiface = None
if usejson:
self.stdheaders['ACCEPT'] = 'application/json'
if host:
self.hosts = [host]
if not nodename:
with open('/etc/confluent/confluent.info') as cinfo:
info = cinfo.read().split('\n')
for line in info:
if line.startswith('NODENAME:'):
nodename = line.split(' ')[1]
self.stdheaders['CONFLUENT_NODENAME'] = nodename
else:
self.hosts = []
try:
info = open('/etc/confluent/confluent.info').read().split('\n')
except Exception:
info = []
havedefault = '0'
plainhost = ''
for line in info:
host = ''
if line.startswith('NODENAME:'):
nodename = line.split(' ')[1]
self.stdheaders['CONFLUENT_NODENAME'] = nodename
if line.startswith('MANAGER:') and not host:
host = line.split(' ')[1]
self.hosts.append(host)
if not plainhost:
plainhost = host
if line.startswith('EXTMGRINFO:'):
extinfo = line.split(' ')[1]
extinfo = extinfo.split('|')
if havedefault == '0' and extinfo[2] == '1':
host, mgtiface, havedefault = extinfo[:3]
if '%' in host:
ifidx = host.split('%', 1)[1]
with open('/tmp/confluent.ifidx', 'w+') as ifout:
ifout.write(ifidx)
if not mgtiface:
host, mgtiface, havedefault = extinfo[:3]
if host:
if havedefault == '0':
if '%' in host:
ifidx = host.split('%', 1)[1]
with open('/tmp/confluent.ifidx', 'w+') as ifout:
ifout.write(ifidx)
self.hosts.append(host)
try:
info = open('/etc/confluent/confluent.deploycfg').read().split('\n')
except Exception:
info = None
if info:
for line in info:
if line.startswith('deploy_server: ') or line.startswith('deploy_server_v6: '):
self.hosts.append(line.split(': ', 1)[1])
if plainhost and not self.hosts:
self.hosts.append(plainhost)
if self.phmac:
self.stdheaders['CONFLUENT_CRYPTHMAC'] = self.phmac
elif not checkonly:
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(nodename, self.hosts, errout=self.errout, hmackey=hmackey, confuuid=self.confuuid)
if mgtiface:
self.stdheaders['CONFLUENT_MGTIFACE'] = mgtiface
self.port = port
self.host = None
self.node = nodename
host = self.check_connections()
client.HTTPConnection.__init__(self, host, port)
self.connect()
def set_header(self, key, val):
self.stdheaders[key] = val
def check_connections(self):
foundsrv = None
hosts = self.hosts
ctx = ssl.SSLContext(_protoparm)
ctx.load_verify_locations('/etc/confluent/ca.pem')
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
for timeo in (0.1, 5):
for host in hosts:
if host in self.ignorehosts:
continue
try:
addrinf = socket.getaddrinfo(host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.settimeout(timeo)
psock.connect(addrinf[4])
chost = host.split('%', 1)[0]
ctx.wrap_socket(psock, server_hostname=chost)
foundsrv = host
psock.close()
break
except (OSError, socket.error):
continue
except ssl.SSLError:
continue
except ssl.CertificateError:
continue
else:
continue
break
if not foundsrv:
srvlist, srvs = scan_confluents(self.confuuid)
hosts = []
for srv in srvlist:
if srvs[srv].get('isdefault', False):
hosts = [srv] + hosts
else:
hosts = hosts + [srv]
for host in hosts:
try:
addrinf = socket.getaddrinfo(host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.settimeout(timeo)
psock.connect(addrinf[4])
foundsrv = host
psock.close()
break
except OSError:
continue
else:
raise Exception('Unable to reach any hosts')
return foundsrv
def connect(self, tries=3):
addrinf = socket.getaddrinfo(self.host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.settimeout(15)
psock.connect(addrinf[4])
ctx = ssl.SSLContext(_protoparm)
ctx.load_verify_locations('/etc/confluent/ca.pem')
host = self.host.split('%', 1)[0]
if '[' not in host and ':' in host:
self.stdheaders['Host'] = '[{0}]'.format(host)
else:
self.stdheaders['Host'] = '{0}'.format(host)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
try:
self.sock = ctx.wrap_socket(psock, server_hostname=host)
except ssl.SSLError:
errmsg = 'Error validating certificate on deployer (try `osdeploy initialize -t` on the deployment server {0})\n'.format(host)
sys.stderr.write(errmsg)
if self.errout:
self.errout.write(errmsg)
self.errout.flush()
sys.exit(1)
except socket.timeout:
if not tries:
raise
return self.connect(tries=tries-1)
def grab_url(self, url, data=None, returnrsp=False):
return self.grab_url_with_status(url, data, returnrsp)[1]
def grab_url_with_status(self, url, data=None, returnrsp=False):
if data:
method = 'POST'
else:
method = 'GET'
authed = False
while not authed:
authed = True
self.request(method, url, data, headers=self.stdheaders)
rsp = self.getresponse()
if rsp.status >= 200 and rsp.status < 300:
if returnrsp:
return rsp.status, rsp
else:
return rsp.status, rsp.read()
if rsp.status == 401:
authed = False
rsp.read()
with open('/etc/confluent/confluent.apikey', 'w+') as akfile:
akfile.write('')
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(
self.node, [self.host], errout=self.errout, hmackey=self.hmackey, confuuid=self.confuuid)
if rsp.status == 503: # confluent is down, but the server running confluent is otherwise up
authed = False
self.ignorehosts.add(self.host)
host = self.check_connections()
client.HTTPConnection.__init__(self, host, self.port)
raise Exception(rsp.read())
def get_current_vmnic_vswitch():
uplinkmatch = re.compile(r'^\s*Uplinks:\s*(.*)')
switchmatch = re.compile(r'^\s*Name:\s*(.*)')
vswinfo = subprocess.check_output(['localcli', 'network', 'vswitch', 'standard', 'list']).decode()
vmnic = None
vswitch_name = None
for info in vswinfo.split('\n'):
name_match = switchmatch.match(info)
if name_match:
vswitch_name = name_match.group(1).strip()
upinfo = uplinkmatch.match(info)
if upinfo:
vmnic = upinfo.group(1).strip()
if vmnic and 'vusb0' not in vmnic:
return vswitch_name, vmnic
return vswitch_name, vmnic
def get_available_nics():
nicinfo = subprocess.check_output(['localcli', 'network', 'nic', 'list']).decode('utf8').split('\n')
available_nics = {}
# Skip headers and separators
parsing_started = False
for line in nicinfo:
if re.match(r'^-+', line):
parsing_started = True
continue
if not parsing_started or not line.strip():
continue
parts = re.split(r'\s{2,}', line.strip())
if len(parts) >= 5:
nic_name = parts[0]
nic_status = parts[4] # "Link Status" is the 5th field
available_nics[nic_name] = nic_status
return available_nics
def is_esxi():
return os.path.isdir("/etc/vmware")
def fix_vswitch():
if is_esxi():
start_time = time.time()
while True:
current_vswitch, current_vmnic = get_current_vmnic_vswitch()
if current_vswitch is None:
raise RuntimeError("Panic: current vswitch is None")
if current_vmnic is None:
raise RuntimeError("Panic: current vmnic is None")
available_nics = get_available_nics()
if current_vmnic and available_nics.get(current_vmnic) == 'Up':
break
new_vmnic = next((nic for nic, status in available_nics.items() if status == 'Up'), None)
if new_vmnic and new_vmnic != current_vmnic:
subprocess.check_call(['localcli', 'network', 'vswitch', 'standard', 'uplink', 'remove',
'--uplink-name', current_vmnic, '--vswitch-name', current_vswitch])
subprocess.check_call(['localcli', 'network', 'vswitch', 'standard', 'uplink', 'add',
'--uplink-name', new_vmnic, '--vswitch-name', current_vswitch])
elif not new_vmnic:
if time.time() - start_time > 300:
break
time.sleep(5)
time.sleep(5)
if __name__ == '__main__':
data = None
if '-f' in sys.argv:
try:
fix_vswitch()
except Exception as e:
print("fix_vswitch() error: {}".format(e))
sys.argv.remove('-f')
sys.exit(0)
usejson = False
if '-j' in sys.argv:
usejson = True
if len(sys.argv) == 1:
HTTPSClient()
sys.exit(0)
try:
outbin = sys.argv.index('-o')
sys.argv.pop(outbin)
outbin = sys.argv.pop(outbin)
except ValueError:
outbin = None
try:
waitfor = sys.argv.index('-w')
sys.argv.pop(waitfor)
waitfor = int(sys.argv.pop(waitfor))
except ValueError:
waitfor = None
try:
data = sys.argv.index('-d')
sys.argv.pop(data)
data = sys.argv.pop(data)
except ValueError:
data = None
try:
errout = sys.argv.index('-e')
sys.argv.pop(errout)
errout = sys.argv.pop(errout)
except ValueError:
errout = None
try:
phmac = sys.argv.index('-p')
sys.argv.pop(phmac)
phmac = sys.argv.pop(phmac)
with open(phmac, 'r') as hmacin:
phmac = hmacin.read()
except ValueError:
phmac = None
try:
identfile = sys.argv.index('-i')
sys.argv.pop(identfile)
identfile = sys.argv.pop(identfile)
with open(identfile) as idin:
data = idin.read()
identinfo = json.loads(data)
nodename = identinfo.get('nodename', None)
hmackey = identinfo.get('apitoken', None)
confuuid = identinfo.get('confluent_uuid', None)
except ValueError:
hmackey = None
nodename = None
confuuid = None
try:
checkonly = False
idxit = sys.argv.index('-c')
sys.argv.pop(idxit)
checkonly = True
except Exception:
pass
if len(sys.argv) > 2 and os.path.exists(sys.argv[-1]):
data = open(sys.argv[-1]).read()
if outbin:
with open(outbin, 'ab+') as outf:
reader = HTTPSClient(usejson=usejson, errout=errout, hmackey=hmackey, nodename=nodename, confuuid=confuuid).grab_url(
sys.argv[1], data, returnrsp=True)
chunk = reader.read(16384)
while chunk:
outf.write(chunk)
chunk = reader.read(16384)
sys.exit(0)
mclient = HTTPSClient(usejson, errout=errout, phmac=phmac, checkonly=checkonly, hmackey=hmackey, nodename=nodename, confuuid=confuuid)
if waitfor:
status = 201
while status != waitfor:
status, rsp = mclient.grab_url_with_status(sys.argv[1], data)
sys.stdout.write(rsp.decode())
elif checkonly:
sys.stdout.write(mclient.check_connections())
else:
try:
sys.stdout.buffer.write(mclient.grab_url(sys.argv[1], data))
except AttributeError:
sys.stdout.write(mclient.grab_url(sys.argv[1], data))