diff --git a/.env b/.env
index 3bb7b21b..298128cc 100755
--- a/.env
+++ b/.env
@@ -49,27 +49,24 @@ DOCKER_API_VERSION=1.40
# Orborus/Proxy configurations
HTTP_PROXY=
HTTPS_PROXY=
-# Decides if proxy configurations should be passed to workers or not
SHUFFLE_PASS_WORKER_PROXY=TRUE
-# Decides if proxy configurations should be passed to apps or not. Requires SHUFFLE_PASS_WORKER_PROXY=true
SHUFFLE_PASS_APP_PROXY=TRUE
-# Used to differentiate proxies for shuffle internal vs external traffic
-SHUFFLE_INTERNAL_HTTP_PROXY=
-SHUFFLE_INTERNAL_HTTPS_PROXY=
+SHUFFLE_INTERNAL_HTTP_PROXY=NOPROXY
+SHUFFLE_INTERNAL_HTTPS_PROXY=NOPROXY
# Timezone-handler in Orborus, Worker and Apps
TZ=Europe/Amsterdam
# Used to FIND the containername. cgroup v2: issue 501
ORBORUS_CONTAINER_NAME=
# Used for setting up a startup delay for Orborus
-SHUFFLE_ORBORUS_STARTUP_DELAY=
-SHUFFLE_SKIPSSL_VERIFY=true
+SHUFFLE_ORBORUS_STARTUP_DELAY=
+SHUFFLE_SKIPSSL_VERIFY=true
# Used for controlling if the environment should run in kubernetes or not
-IS_KUBERNETES=false
+IS_KUBERNETES=false
-SHUFFLE_BASE_IMAGE_NAME=shuffle
-SHUFFLE_BASE_IMAGE_REGISTRY=ghcr.io
+#SHUFFLE_BASE_IMAGE_NAME=shuffle
+#SHUFFLE_BASE_IMAGE_REGISTRY=ghcr.io
SHUFFLE_BASE_IMAGE_REPOSITORY=frikky
-SHUFFLE_BASE_IMAGE_TAG_SUFFIX="-1.3.1"
+#SHUFFLE_BASE_IMAGE_TAG_SUFFIX="-1.4.0"
# The eth0 interface inside a container corresponds
# to the virtual Ethernet interface that connects
@@ -100,8 +97,8 @@ SHUFFLE_MAX_EXECUTION_DEPTH=
DATASTORE_EMULATOR_HOST=shuffle-database:8000
#SHUFFLE_OPENSEARCH_URL=http://shuffle-opensearch:9200
SHUFFLE_OPENSEARCH_URL=https://shuffle-opensearch:9200
-SHUFFLE_OPENSEARCH_USERNAME=admin
-SHUFFLE_OPENSEARCH_PASSWORD=admin
+SHUFFLE_OPENSEARCH_USERNAME="admin"
+SHUFFLE_OPENSEARCH_PASSWORD="StrongShufflePassword321!"
SHUFFLE_OPENSEARCH_CERTIFICATE_FILE=
SHUFFLE_OPENSEARCH_APIKEY=
SHUFFLE_OPENSEARCH_CLOUDID=
@@ -109,4 +106,8 @@ SHUFFLE_OPENSEARCH_PROXY=
SHUFFLE_OPENSEARCH_INDEX_PREFIX=
SHUFFLE_OPENSEARCH_SKIPSSL_VERIFY=true
+#Tenzir related
+SHUFFLE_TENZIR_URL=
+
+
DEBUG_MODE=false
diff --git a/.github/install-guide.md b/.github/install-guide.md
index f033838a..aa763642 100755
--- a/.github/install-guide.md
+++ b/.github/install-guide.md
@@ -6,16 +6,19 @@ Shuffle Installation
-Installation of Shuffle is currently available for docker and kubernetes. Looking for how to update Shuffle? Check the [updating guide](https://shuffler.io/docs/configuration#updating_shuffle)
+Installation of Shuffle is currently available for [docker](https://shuffler.io/docs/configuration#production-readiness) and [kubernetes](https://shuffler.io/docs/configuration#Kubernetes).
-This document outlines an introduction environment which is not scalable. [Read here](https://shuffler.io/docs/configuration#production_readiness) for information on production readiness. This also includes system requirements and configurations for Swarm or Kubernetes.
+- Looking to run workflows onprem, but don't want to run the entire stack? Looks into [Environments & Orborus hosting Onprem](https://shuffler.io/docs/organizations#Environments)
+- Looking for how to update Shuffle? Check the [updating guide](https://shuffler.io/docs/configuration#updating_shuffle)
+
+This document outlines an introduction environment which is **not** scalable. [Read here](https://shuffler.io/docs/configuration#production_readiness) for information on production readiness and scalability. This also includes system requirements and configurations for **Docker Swarm** or **Kubernetes**.
# Docker - *nix
-The Docker setup is done with docker-compose
+The Docker setup is the default setup, and is ran with docker compose. This is [NOT a scalable build](https://shuffler.io/docs/configuration#production-readiness) without changes.
**PS: if you're setting up Shuffle on Windows, go to the next step (Windows Docker setup)**
-1. Make sure you have [Docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/) installed, and that you have a minimum of **2Gb of RAM** available.
+1. Make sure you have [Docker](https://docs.docker.com/get-docker/) installed, and that you have a minimum of **2Gb of RAM** available.
2. Download Shuffle
```bash
git clone https://github.com/Shuffle/Shuffle
@@ -32,7 +35,7 @@ sudo swapoff -a # Disable swap
4. Run docker-compose.
```bash
-docker-compose up -d
+docker compose up -d
```
5. Recommended for Opensearch to work well
@@ -40,7 +43,7 @@ docker-compose up -d
sudo sysctl -w vm.max_map_count=262144 # https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html
```
-When you're done, skip to the [After installation](#after-installation) step below.
+When you're done, go to the [After installation](#after-installation) step below.
## Windows with WSL
This step is for setting up with Docker on windows from scratch.
@@ -57,9 +60,9 @@ This step is for setting up with Docker on windows from scratch.
OUTER_HOSTNAME=YOUR.IP.HERE
```
-6. Run docker-compose
+5. Run docker compose
```bash
-docker-compose up -d
+docker compose up -d
```
### Configurations (high availability, scale, proxies, default users etc.)
@@ -124,8 +127,8 @@ Large portions of the backend is written in another repository - [shuffle-shared
## Database - Opensearch
Make sure this is running through the docker-compose, and that the backend points to it with SHUFFLE_OPENSEARCH_URL defined.
-So essentially, what that means is:
-1. Make sure you have docker-compose installed
+What it means:
+1. Make sure you have docker compose installed
2. Make sure you have the docker-compose.yml file from this repository
3. Run `docker-compose up opensearch -d`
diff --git a/.github/workflows/dockerbuild.yaml b/.github/workflows/dockerbuild.yaml
index 0411279e..a14dfaa9 100644
--- a/.github/workflows/dockerbuild.yaml
+++ b/.github/workflows/dockerbuild.yaml
@@ -3,7 +3,7 @@ name: dockerbuild
on:
push:
branches:
- - main
+ - 1.4.0
paths:
- "**"
- "!.github/**"
@@ -19,23 +19,23 @@ jobs:
include:
- app: frontend
path: frontend
- version: 1.3.3
+ version: 1.4.0
experimental: true
- app: backend
path: backend
- version: 1.3.3
+ version: 1.4.0
experimental: true
- app: app_sdk
path: backend/app_sdk
- version: 1.3.3
+ version: 1.4.0
experimental: true
- app: orborus
path: functions/onprem/orborus
- version: 1.3.3
+ version: 1.4.0
experimental: true
- app: worker
path: functions/onprem/worker
- version: 1.3.3
+ version: 1.4.0
experimental: true
steps:
- name: Checkout
diff --git a/backend/Dockerfile b/backend/Dockerfile
index cb287e8f..e34f9c11 100755
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.19.3-buster as builder
+FROM golang:1.22 as builder
# Add files
RUN mkdir /app
@@ -41,4 +41,4 @@ COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certifica
WORKDIR /app
EXPOSE 5001
-CMD ["./webapp"]
\ No newline at end of file
+CMD ["./webapp"]
diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py
index 3937b052..15338d89 100755
--- a/backend/app_sdk/app_base.py
+++ b/backend/app_sdk/app_base.py
@@ -25,6 +25,11 @@ import concurrent.futures
from io import StringIO as StringBuffer, BytesIO
from liquid import Liquid, defaults
+from requests.packages.urllib3.exceptions import InsecureRequestWarning
+
+# Suppress the warning
+requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
+
runtime = os.getenv("SHUFFLE_SWARM_CONFIG", "")
@@ -96,6 +101,7 @@ def md5_base64(a):
@shuffle_filters.register
def base64_encode(a):
a = str(a)
+
try:
return base64.b64encode(a.encode('utf-8')).decode()
except:
@@ -104,6 +110,17 @@ def base64_encode(a):
@shuffle_filters.register
def base64_decode(a):
a = str(a)
+
+ if "-" in a:
+ a = a.replace("-", "+", -1)
+
+ if "_" in a:
+ a = a.replace("_", "/", -1)
+
+ # Fix padding
+ if len(a) % 4 != 0:
+ a += "=" * (4 - len(a) % 4)
+
try:
return base64.b64decode(a).decode("unicode_escape")
except:
@@ -121,7 +138,7 @@ def as_object(a):
return json.loads(str(a))
@shuffle_filters.register
-def ast(a):
+def ast_eval(a):
return ast.literal_eval(str(a))
@shuffle_filters.register
@@ -231,7 +248,6 @@ def csv_parse(a):
try:
return json.dumps(allitems)
except:
- print("[ERROR] Failed dumping from JSON in csv parse")
return allitems
@shuffle_filters.register
@@ -259,13 +275,6 @@ def split(base, sep):
except:
return base.split(sep)
-#print(shuffle_filters.filters)
-#print(Liquid("{{ '10' | plus: 1}}", filters=shuffle_filters.filters).render())
-#print(Liquid("{{ '10' | minus: 1}}", filters=shuffle_filters.filters).render())
-#print(Liquid("{{ asd | size }}", filters=shuffle_filters.filters).render())
-#print(Liquid("{{ 'asd' | md5 }}", filters=shuffle_filters.filters).render())
-#print(Liquid("{{ 'asd' | sha256 }}", filters=shuffle_filters.filters).render())
-#print(Liquid("{{ 'asd' | md5_base64 | base64_decode }}", filters=shuffle_filters.filters).render())
###
###
@@ -339,44 +348,39 @@ class AppBase:
if self.proxy_config["https"].lower() == "noproxy":
self.proxy_config["https"] = ""
except Exception as e:
- self.logger.info(f"[DEBUG] Failed setting proxy config: {e}. NOT important if running apps with webserver. This is NOT critical.")
+ self.logger.info(f"[WARNING] Failed setting proxy config: {e}. NOT important if running apps with webserver. This is NOT critical.")
- self.logger.info(f"[DEBUG] Proxy config: {self.proxy_config}")
if isinstance(self.action, str):
try:
self.action = json.loads(self.action)
self.original_action = json.loads(self.action)
except Exception as e:
- self.logger.info(f"[DEBUG] Failed parsing action as JSON (init): {e}. NOT important if running apps with webserver. This is NOT critical.")
-
- #print(f"ACTION: {self.action}")
+ pass
if len(self.base_url) == 0:
self.base_url = self.url
+
+ self.local_storage = []
+
# Checks output for whether it should be automatically parsed or not
def run_magic_parser(self, input_data):
if not isinstance(input_data, str):
- self.logger.info("[DEBUG] Not string. Returning from magic")
return input_data
# Don't touch existing JSON/lists
if (input_data.startswith("[") and input_data.endswith("]")) or (input_data.startswith("{") and input_data.endswith("}")):
- self.logger.info("[DEBUG] Already JSON-like. Returning from magic")
return input_data
if len(input_data) < 3:
- self.logger.info("[DEBUG] Too short input data")
return input_data
# Don't touch large data.
if len(input_data) > 100000:
- self.logger.info("[DEBUG] Value too large. Returning from magic")
return input_data
if not "\n" in input_data and not "," in input_data:
- self.logger.info("[DEBUG] No data to autoparse - requires newline or comma")
return input_data
new_input = input_data
@@ -398,7 +402,6 @@ class AppBase:
index += 1
continue
- #print("FIX ITEM %s" % item)
for subitem in item.split(splititem):
new_return.insert(index, subitem)
@@ -406,7 +409,7 @@ class AppBase:
# Prevent large data or infinite loops
if index > 10000:
- self.logger.info(f"[DEBUG] Infinite loop. Returning default data.")
+ #self.logger.info(f"[DEBUG] Infinite loop. Returning default data.")
return input_data
fixed_return = []
@@ -466,14 +469,133 @@ class AppBase:
"success": True,
"status": request.status_code,
"url": request.url,
- "headers": parsedheaders,
"body": jsondata,
+ "headers": parsedheaders,
"cookies":cookies,
})
except Exception as e:
- print(f"[WARNING] Failed in request: {e}")
return request.text
+ # Fixes pattern issues in json/liquid based on input and supplied patterns
+ def patternfix_string(self, liquiddata, patterns, regex_patterns, inputtype="liquid"):
+ if not inputtype or inputtype == "liquid":
+ if "{{" not in liquiddata or "}}" not in liquiddata:
+ return liquiddata
+ elif inputtype == "json":
+ liquiddata = liquiddata.strip()
+
+ # Validating if it looks like json or not
+ if liquiddata[0] == "{" and liquiddata[len(liquiddata)-1] == "}":
+ pass
+ else:
+ if liquiddata[0] == "[" and liquiddata[len(liquiddata)-1] == "]":
+ pass
+ else:
+ return liquiddata
+
+ # If it's already json, don't touch it
+ try:
+ json.loads(liquiddata)
+ return liquiddata
+ except Exception as e:
+ pass
+ else:
+ print("No replace handler for %s" % inputtype)
+ return liquiddata
+
+ skipkeys = [" "]
+ newoutput = liquiddata[:]
+ for pattern in patterns:
+ keylocations = []
+ parsedvalue = ""
+ record = False
+ index = -1
+ for key in liquiddata:
+
+ # Return instant if possible
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ pass
+
+ index += 1
+ if not key:
+ if record:
+ keylocations.append(index)
+ parsedvalue += key
+
+ continue
+
+ if key in skipkeys:
+ if record:
+ keylocations.append(index)
+ parsedvalue += key
+
+ continue
+
+ if key == pattern[0] and not record:
+ record = True
+
+ if key not in pattern:
+ keylocations = []
+ parsedvalue = ""
+ record = False
+
+ if record:
+ keylocations.append(index)
+ parsedvalue += key
+
+ if len(parsedvalue) == 0:
+ continue
+
+ evaluated_value = parsedvalue[:]
+ for skipkey in skipkeys:
+ evaluated_value = "".join(evaluated_value.split(skipkey))
+
+ if evaluated_value == pattern:
+ #print("Found matching: %s (%s)" % (parsedvalue, keylocations))
+ #print("Should replace with: %s" % patterns[pattern])
+
+ newoutput = newoutput.replace(parsedvalue, patterns[pattern], -1)
+
+ # Return instant if possible
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ pass
+
+
+ for pattern in regex_patterns:
+ newlines = []
+ for line in newoutput.split("\n"):
+ replaced_line = re.sub(pattern, regex_patterns[pattern], line)
+ newlines.append(replaced_line)
+
+ newoutput = "\n".join(newlines)
+
+ # Return instant if possible
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ pass
+
+ # Dont return json properly unless actually json
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ # Returns original if json fixing didn't work
+ return liquiddata
+
+ return newoutput
+
# FIXME: Add more info like logs in here.
# Docker logs: https://forums.docker.com/t/docker-logs-inside-the-docker-container/68190/2
def send_result(self, action_result, headers, stream_path):
@@ -481,40 +603,29 @@ class AppBase:
action_result["status"] = "FAILURE"
try:
- #self.logger.info(f"[DEBUG] ACTION: {self.action}")
if self.action["run_magic_output"] == True:
- self.logger.warning(f"[INFO] Action result ran with Magic parser output.")
action_result["result"] = self.run_magic_parser(action_result["result"])
- else:
- self.logger.warning(f"[WARNING] Magic output not defined.")
except KeyError as e:
- #self.logger.warning(f"[DEBUG] Failed to run magic autoparser (send result) - keyerror: {e}")
pass
except Exception as e:
- #self.logger.warning(f"[DEBUG] Failed to run magic autoparser (send result): {e}")
pass
# Try it with some magic
action_result["completed_at"] = int(time.time_ns())
- self.logger.info(f"""[DEBUG] Inside Send result with status {action_result["status"]}""")
#if isinstance(action_result,
# FIXME: Add cleanup of parameters to not send to frontend here
params = {}
# I wonder if this actually works
- self.logger.info(f"[DEBUG] Before last stream result")
url = "%s%s" % (self.base_url, stream_path)
- self.logger.info(f"[INFO] URL FOR RESULT (URL): {url}")
try:
log_contents = "disabled: add env SHUFFLE_LOGS_DISABLED=true to Orborus to re-enable logs for apps. Can not be enabled natively in Cloud except in Hybrid mode."
if not os.getenv("SHUFFLE_LOGS_DISABLED") == "true":
log_contents = self.log_capture_string.getvalue()
- #print("RESULTS: %s" % log_contents)
- self.logger.info(f"[WARNING] Got logs of length {len(log_contents)}")
if len(action_result["action"]["parameters"]) == 0:
action_result["action"]["parameters"] = []
@@ -531,7 +642,7 @@ class AppBase:
})
except Exception as e:
- print(f"[WARNING] Failed adding parameter for logs: {e}")
+ pass
try:
finished = False
@@ -543,23 +654,22 @@ class AppBase:
try:
ret = requests.post(url, headers=headers, json=action_result, timeout=10, verify=False, proxies=self.proxy_config)
- self.logger.info(f"""[DEBUG] Successful request result request: Status= {ret.status_code} (break on 200/201) & Response= {ret.text}. Action status: {action_result["status"]}""")
+ #self.logger.info(f"""[DEBUG] Successful result request: Status= {ret.status_code} (break on 200/201) & Action status: {action_result["status"]}. Response= {ret.text}""")
if ret.status_code == 200 or ret.status_code == 201:
finished = True
break
else:
- self.logger.info(f"[ERROR] Bad resp {ret.status_code}: {ret.text}")
+ # FIXME: Add a checker for 403, and Proxy logs failing
+ self.logger.info(f"[ERROR] Bad resp ({ret.status_code}) in send_result for url '{url}'")
time.sleep(sleeptime)
# Proxyerrror
except requests.exceptions.ProxyError as e:
- self.logger.info(f"[ERROR] Proxy error for url {url}: {e}")
self.proxy_config = {}
continue
except requests.exceptions.RequestException as e:
- self.logger.info(f"[DEBUG] Request problem for url {url}: {e}")
time.sleep(sleeptime)
# Check if we have a read timeout. If we do, exit as we most likely sent the result without getting a good result
@@ -576,25 +686,21 @@ class AppBase:
#time.sleep(5)
continue
except TimeoutError as e:
- self.logger.info(f"[DEBUG] Timeout or request: {e}")
time.sleep(sleeptime)
#time.sleep(5)
continue
except requests.exceptions.ConnectionError as e:
- self.logger.info(f"[DEBUG] Connectionerror: {e}")
time.sleep(sleeptime)
#time.sleep(5)
continue
except http.client.RemoteDisconnected as e:
- self.logger.info(f"[DEBUG] Remote: {e}")
time.sleep(sleeptime)
#time.sleep(5)
continue
except urllib3.exceptions.ProtocolError as e:
- self.logger.info(f"[DEBUG] Protocol err: {e}")
time.sleep(0.1)
#time.sleep(5)
@@ -606,24 +712,22 @@ class AppBase:
# Not sure why this would work tho :)
action_result["status"] = "FAILURE"
action_result["result"] = json.dumps({"success": False, "reason": "POST error: Failed connecting to %s over 10 retries to the backend" % url})
- self.logger.info(f"[ERROR] Before typeerror stream result - NOT finished after 10 requests")
-
self.send_result(action_result, {"Content-Type": "application/json", "Authorization": "Bearer %s" % self.authorization}, "/api/v1/streams")
return
except requests.exceptions.ConnectionError as e:
- self.logger.info(f"[DEBUG] Unexpected ConnectionError happened: {e}")
+ #self.logger.info(f"[DEBUG] Unexpected ConnectionError happened: {e}")
+ pass
except TypeError as e:
action_result["status"] = "FAILURE"
action_result["result"] = json.dumps({"success": False, "reason": "Typeerror when sending to backend URL %s" % url})
- self.logger.info(f"[DEBUG] Before typeerror stream result: {e}")
ret = requests.post("%s%s" % (self.base_url, stream_path), headers=headers, json=action_result, verify=False, proxies=self.proxy_config)
#self.logger.info(f"[DEBUG] Result: {ret.status_code}")
#if ret.status_code != 200:
# pr
- self.logger.info(f"[DEBUG] TypeError request: Status= {ret.status_code} & Response= {ret.text}")
+ #self.logger.info(f"[DEBUG] TypeError request: Status= {ret.status_code} & Response= {ret.text}")
except http.client.RemoteDisconnected as e:
self.logger.info(f"[DEBUG] Expected Remotedisconnect happened: {e}")
except urllib3.exceptions.ProtocolError as e:
@@ -638,7 +742,6 @@ class AppBase:
#self.log_capture_string.close()
#pass
except Exception as e:
- print(f"[WARNING] Failed to flush logs: {e}")
pass
#async def cartesian_product(self, L):
@@ -658,13 +761,6 @@ class AppBase:
#self.logger.info("ITS A LIST!")
newlist = params
- #self.full_execution = os.getenv("FULL_EXECUTION", "")
- #self.logger.info(len(params))
- #self.logger.info(params.items())
- #self.logger.info(list(params.items()))
- #self.logger.info(f"PARAM: {params}")
- #self.logger.info(f"NEWLIST: {newlist}")
-
# FIXME: Also handle MULTI PARAM
values = []
param_names = []
@@ -743,9 +839,6 @@ class AppBase:
#self.logger.info(f"DATA: {data}")
# 1594869a676630b397bc34f7dc0951a3
- #self.logger.info(f"VALUE URL: {url}")
- #self.logger.info(f"RET: {ret.text}")
- #self.logger.info(f"ID: {ret.status_code}")
url = f"{self.url}/api/v1/orgs/{org_id}/validate_app_values"
ret = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
if ret.status_code == 200:
@@ -840,7 +933,6 @@ class AppBase:
check_value = ""
for param in self.original_action["parameters"]:
if param["name"] == key:
- #self.logger.info("PARAM: %s" % param)
check_value = param["value"]
# self.result_wrapper_count = 0
@@ -901,7 +993,6 @@ class AppBase:
#self.logger.info(f"MERGE: {should_merge}")
if isinstance(value, list):
- self.logger.info(f"[DEBUG] Item {value} is a list.")
if len(value) <= 1:
if len(value) == 1:
baseparams[key] = value[0]
@@ -932,27 +1023,21 @@ class AppBase:
self.logger.info("[DEBUG] NO multiplier. Running a single iteration.")
paramlist.append(baseparams)
elif len(listlengths) == 1:
- self.logger.info("[DEBUG] NO MULTIPLIER NECESSARY. Length is %d" % len(listitems))
-
for item in listitems:
# This loops should always be length 1
for key, value in item.items():
if isinstance(value, int):
- self.logger.info("\n[DEBUG] Should run key %s %d times from %s" % (key, value, baseparams[key]))
if len(paramlist) == value:
- self.logger.info("[DEBUG] List ALREADY exists - just changing values")
for subloop in range(value):
baseitem = copy.deepcopy(baseparams)
paramlist[subloop][key] = baseparams[key][subloop]
else:
- self.logger.info("[DEBUG] List DOESNT exist - ADDING values")
for subloop in range(value):
baseitem = copy.deepcopy(baseparams)
baseitem[key] = baseparams[key][subloop]
paramlist.append(baseitem)
else:
- self.logger.info("[DEBUG] Multipliers to handle: %s" % listitems)
newlength = 1
for item in listitems:
for key, value in item.items():
@@ -1006,11 +1091,9 @@ class AppBase:
if key != "body":
value[0] = json.loads(value[0])
except json.decoder.JSONDecodeError as e:
- self.logger.info("[WARNING] JSON casting error (1): %s" % e)
+ pass
except TypeError as e:
- self.logger.info("[WARNING] TypeError: %s" % e)
-
- self.logger.info("[DEBUG] POST initial list check")
+ pass
try:
if isinstance(value, list) and len(value) == 1 and isinstance(value[0], list):
@@ -1020,7 +1103,6 @@ class AppBase:
self.logger.info("[WARNING] Exception in loop wrapper: {e}")
loop_wrapper[key] = 1
- self.logger.info(f"[DEBUG] Key {key} is a list: {value}")
newparams[key] = value[0]
has_loop = True
else:
@@ -1045,6 +1127,8 @@ class AppBase:
#param_multiplier = await self.get_param_multipliers(newparams)
param_multiplier = self.get_param_multipliers(newparams)
+ #self.logger.info("PARAM MULTIPLIER: %s" % param_multiplier)
+
# FIXME: This does a deduplication of the data
new_params = self.validate_unique_fields(param_multiplier)
#self.logger.info(f"NEW PARAMS: {new_params}")
@@ -1070,7 +1154,6 @@ class AppBase:
#self.logger.info(f"NEW PARAMS: {new_params}")
param_multiplier = new_params
- #self.logger.info("Returned with newparams of length %d", len(new_params))
#if isinstance(new_params, list) and len(new_params) == 1:
# params = new_params[0]
#else:
@@ -1081,10 +1164,9 @@ class AppBase:
# self.send_result(action_result, headers, stream_path)
# return
- self.logger.info("[INFO] Multiplier length: %d" % len(param_multiplier))
- #tmp = ""
for subparams in param_multiplier:
#self.logger.info(f"SUBPARAMS IN MULTI: {subparams}")
+ tmp = ""
try:
while True:
@@ -1107,8 +1189,8 @@ class AppBase:
else:
raise Exception(json.dumps({
"success": False,
- "reason": "You may be running an old version of this action. Please delete and remake the node.",
"exception": f"TypeError: {e}",
+ "reason": "You may be running an old version of this action. Please delete and remake the node.",
}))
break
@@ -1147,7 +1229,6 @@ class AppBase:
except Exception as e:
self.logger.warning("[ERROR] Failed to parse coroutine value for old app: {e}")
- #self.logger.info("RET from execution: %s" % ret)
new_value = tmp
if tmp == None:
new_value = ""
@@ -1212,7 +1293,7 @@ class AppBase:
return results
# Downloads all files from a namespace
- # Currently only working on local version of Shuffle
+ # Currently only working on local version of Shuffle (2023)
def get_file_category_ids(self, category):
org_id = self.full_execution["workflow"]["execution_org"]["id"]
@@ -1283,8 +1364,6 @@ class AppBase:
full_execution = self.full_execution
org_id = full_execution["workflow"]["execution_org"]["id"]
- self.logger.info("SHOULD GET FILES BASED ON ORG %s, workflow %s and value(s) %s" % (org_id, full_execution["workflow"]["id"], value))
-
if isinstance(value, list):
self.logger.info("IS LIST!")
#if len(value) == 1:
@@ -1294,9 +1373,16 @@ class AppBase:
returns = []
for item in value:
- self.logger.info("VALUE: %s" % item)
+ self.logger.info("FILE VALUE: %s" % item)
+ # Check if item is a dict, and if it is, check if it has the key "id"
+ if isinstance(item, dict):
+ if "file_id" in item:
+ item = item["file_id"]
+ elif "id" in item:
+ item = item["id"]
+
if len(item) != 36 and not item.startswith("file_"):
- self.logger.info("Bad length for file value %s" % item)
+ self.logger.info("Bad length for file value: '%s'" % item)
continue
#return {
# "filename": "",
@@ -1312,7 +1398,6 @@ class AppBase:
}
ret1 = requests.get("%s%s" % (self.url, get_path), headers=headers, verify=False, proxies=self.proxy_config)
- self.logger.info("RET1 (file get): %s" % ret1.text)
if ret1.status_code != 200:
returns.append({
"filename": "",
@@ -1323,7 +1408,6 @@ class AppBase:
content_path = "/api/v1/files/%s/content?execution_id=%s" % (item, full_execution["execution_id"])
ret2 = requests.get("%s%s" % (self.url, content_path), headers=headers, verify=False, proxies=self.proxy_config)
- self.logger.info("RET2 (file get) done")
if ret2.status_code == 200:
tmpdata = ret1.json()
returndata = {
@@ -1333,8 +1417,6 @@ class AppBase:
}
returns.append(returndata)
- self.logger.info("RET3 (file get done)")
-
if len(returns) == 0:
return {
"success": False,
@@ -1358,6 +1440,19 @@ class AppBase:
"key": key,
}
+ try:
+ newstorage = []
+ for item in self.local_storage:
+ if item["execution_id"] == self.current_execution_id and item["key"] == key:
+ continue
+
+ newstorage.append(item)
+
+ self.local_storage = newstorage
+
+ except Exception as e:
+ print("[ERROR] Failed DELETING current execution id local storage: %s" % e)
+
response = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
try:
allvalues = response.json()
@@ -1379,6 +1474,19 @@ class AppBase:
"value": str(value),
}
+ try:
+ newstorage = []
+ for item in self.local_storage:
+ if item["execution_id"] == self.current_execution_id and item["key"] == key:
+ continue
+
+ newstorage.append(item)
+
+ self.local_storage = newstorage
+
+ except Exception as e:
+ print("[ERROR] Failed SETTING current execution id local storage: %s" % e)
+
response = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
try:
allvalues = response.json()
@@ -1401,12 +1509,23 @@ class AppBase:
"key": key,
}
+ # Makes it so that loops for the same action doesn't re-ask the db unless necessary
+ try:
+ for item in self.local_storage:
+ if item["execution_id"] == self.current_execution_id and item["key"] == key:
+ # Max keeping the local cache properly for 5 seconds due to workflow continuations
+ elapsed_time = time.time() - item["time_set"]
+ if elapsed_time > 5:
+ break
+
+ return item["data"]
+ except Exception as e:
+ print("[ERROR] Failed getting current execution id local storage: %s" % e)
+
value = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
try:
allvalues = value.json()
- self.logger.info("VAL1: ", allvalues)
allvalues["key"] = key
- self.logger.info("VAL2: ", allvalues)
try:
parsedvalue = json.loads(allvalues["value"])
@@ -1414,6 +1533,14 @@ class AppBase:
except:
self.logger.info("Parsing of value as JSON failed. Continue anyway!")
+ try:
+ newdata = json.loads(json.dumps(data))
+ newdata["time_set"] = time.time()
+ newdata["data"] = allvalues
+ self.local_storage.append(newdata)
+ except Exception as e:
+ print("[ERROR] Failed in local storage append: %s" % e)
+
return allvalues
except:
self.logger.info("Value couldn't be parsed, or json dump of value failed")
@@ -1459,7 +1586,6 @@ class AppBase:
#self.logger.info(f"Ret CREATE: {ret.text}")
cur_id = ""
if ret.status_code == 200:
- #self.logger.info("RET: %s" % ret.text)
ret_json = ret.json()
if not ret_json["success"]:
self.logger.info("Not success in file upload creation.")
@@ -1482,16 +1608,12 @@ class AppBase:
}
upload_path = "/api/v1/files/%s/upload?execution_id=%s" % (cur_id, full_execution["execution_id"])
- self.logger.info("Create path: %s" % create_path)
files={"shuffle_file": (filename, curfile["data"])}
#open(filename,'rb')}
ret = requests.post("%s%s" % (self.url, upload_path), files=files, headers=new_headers, verify=False, proxies=self.proxy_config)
- self.logger.info("Ret UPLOAD: %s" % ret.text)
- self.logger.info("Ret2 UPLOAD: %d" % ret.status_code)
- self.logger.info("IDS TO RETURN: %s" % file_ids)
return file_ids
#async def execute_action(self, action):
@@ -1521,7 +1643,6 @@ class AppBase:
pass
self.action = copy.deepcopy(action)
- self.logger.info(f"[DEBUG] Sending starting action result (EXECUTING). Param replace: {replace_params}")
headers = {
"Content-Type": "application/json",
@@ -1550,7 +1671,6 @@ class AppBase:
# Add async logger
# self.console_logger.handlers[0].stream.set_execution_id()
- #self.logger.info("Before initial stream result")
# FIXME: Shouldn't skip this, but it's good for minimzing API calls
#try:
@@ -1580,7 +1700,6 @@ class AppBase:
}
resultsurl = "%s/api/v1/streams/results" % (self.base_url)
- #self.logger.info("[DEBUG] Before FULLEXEC stream result url '%s'" % (resultsurl))
ret = requests.post(
resultsurl,
headers=headers,
@@ -1655,12 +1774,28 @@ class AppBase:
self.full_execution = fullexecution
- #try:
- # if "backend_url" in self.full_execution:
- # self.url = self.full_execution["backend_url"]
- # self.base_url = self.full_execution["backend_url"]
- #except KeyError:
- # pass
+ found_id = ""
+ try:
+ if "execution_id" in self.full_execution and len(self.full_execution["execution_id"]) > 0:
+ found_id = self.full_execution["execution_id"]
+ elif len(self.current_execution_id) > 0:
+ found_id = self.current_execution_id
+ except Exception as e:
+ print("[ERROR] Failed in get full exec")
+
+ try:
+ contains_body = False
+ parameter_count = 0
+
+ if "parameters" in self.action:
+ parameter_count = len(self.action["parameters"])
+ for param in self.action["parameters"]:
+ if param["name"] == "body":
+ contains_body = True
+
+ print("[DEBUG][%s] Action name: %s, Params: %d, Has Body: %s" % (self.current_execution_id, self.action["name"], parameter_count, str(contains_body)))
+ except Exception as e:
+ print("[ERROR] Failed in init print handler: %s" % e)
try:
if replace_params == True:
@@ -1668,7 +1803,8 @@ class AppBase:
self.logger.info("[DEBUG] ID: %s vs %s" % (inner_action["id"], self.action["id"]))
# In case of some kind of magic, we're just doing params
- if inner_action["id"] == self.action["id"]:
+ if inner_action["id"] != self.action["id"]:
+ continue
self.logger.info("FOUND!")
if isinstance(self.action, str):
@@ -1687,8 +1823,6 @@ class AppBase:
except Exception as e:
self.logger.info(f"[WARNING] Failed in replace params action parsing: {e}")
- self.logger.info(f"[DEBUG] AFTER FULLEXEC stream result (init): {self.current_execution_id}")
-
# Gets the value at the parenthesis level you want
def parse_nested_param(string, level):
"""
@@ -1807,9 +1941,9 @@ class AppBase:
return f"join({data})"
except (KeyError, IndexError) as e:
- print(f"ERROR in join(): {e}")
+ pass
except json.decoder.JSONDecodeError as e:
- print(f"JSON ERROR in join(): {e}")
+ pass
if "len" in thistype or "length" in thistype or "lenght" in thistype:
#self.logger.info(f"Trying to length-parse: {data}")
@@ -1914,7 +2048,6 @@ class AppBase:
c_parentheses = parse_nested_param(parse_string, 0)[0]
match_string = re.escape(c_parentheses)
custom_casting = re.findall(fr"({wrapper_group})\({match_string}", parse_string)
- print("[DEBUG] In ELSE: %s" % custom_casting)
# check if a wrapper was found
if len(custom_casting) != 0:
inner_result = parse_type(c_parentheses, custom_casting[0])
@@ -1926,7 +2059,6 @@ class AppBase:
else:
parse_string = inner_result
- #print("PARSE STRING: %s" % parse_string)
return parse_string, True
# Looks for parantheses to grab special cases within a string, e.g:
@@ -2021,6 +2153,7 @@ class AppBase:
return " ".join(newlist)
# Parses JSON loops and such down to the item you're looking for
+ # Check recurse_test.py for examples and tests of this function
# $nodename.#.id
# $nodename.data.#min-max.info.id
# $nodename.data.#1-max.info.id
@@ -2048,7 +2181,7 @@ class AppBase:
for innervalue in basejson:
# 1. Check the next item (message)
# 2. Call this function again
-
+
try:
ret, is_loop = recurse_json(innervalue, parsersplit[outercnt+1:])
except IndexError:
@@ -2073,11 +2206,8 @@ class AppBase:
if isinstance(seconditem, int):
seconditem = str(seconditem)
- #print("[DEBUG] ACTUAL PARSED: %s" % actualitem)
-
# Means it's a single item -> continue
if seconditem == "":
- print("[INFO] In first - handling %s. Len: %d" % (firstitem, len(basejson)))
if str(firstitem).lower() == "max" or str(firstitem).lower() == "last" or str(firstitem).lower() == "end":
firstitem = len(basejson)-1
elif str(firstitem).lower() == "min" or str(firstitem).lower() == "first":
@@ -2085,14 +2215,12 @@ class AppBase:
else:
firstitem = int(firstitem)
- print(f"[DEBUG] Post lower checks with item {firstitem}")
tmpitem = basejson[int(firstitem)]
try:
newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:])
except IndexError:
newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:])
else:
- print("[INFO] In ELSE - handling %s and %s" % (firstitem, seconditem))
if isinstance(firstitem, str):
if firstitem.lower() == "max" or firstitem.lower() == "last" or firstitem.lower() == "end":
firstitem = len(basejson)-1
@@ -2113,7 +2241,6 @@ class AppBase:
else:
seconditem = int(seconditem)
- print(f"[DEBUG] Post lower checks 2: {firstitem} AND {seconditem}")
newvalue = []
if int(seconditem) > len(basejson):
seconditem = len(basejson)
@@ -2121,12 +2248,10 @@ class AppBase:
for i in range(int(firstitem), int(seconditem)+1):
# 1. Check the next item (message)
# 2. Call this function again
- #self.logger.info("Base: %s" % basejson[i])
try:
ret, tmp_loop = recurse_json(basejson[i], parsersplit[outercnt+1:])
except IndexError:
- print("[DEBUG] INDEXERROR: ", parsersplit[outercnt])
#ret = innervalue
ret, tmp_loop = recurse_json(basejson[i], parsersplit[outercnt:])
@@ -2137,16 +2262,13 @@ class AppBase:
else:
if len(value) == 0:
return basejson, False
-
+
try:
if isinstance(basejson, list):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
return basejson, False
elif isinstance(basejson, bool):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (bool): %s" % value)
return basejson, False
elif isinstance(basejson, int):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (int): %s" % value)
return basejson, False
elif isinstance(basejson[value], str):
try:
@@ -2154,14 +2276,17 @@ class AppBase:
basejson = json.loads(basejson[value])
else:
# Should we sanitize here?
- self.logger.info("[DEBUG] VALUE TO SANITIZE?: %s" % basejson[value])
- return str(basejson[value]), False
+ # Check if we are on the last item?
+ if outercnt == len(parsersplit)-1:
+ return str(basejson[value]), False
+ else:
+ pass
+
except json.decoder.JSONDecodeError as e:
return str(basejson[value]), False
else:
basejson = basejson[value]
except KeyError as e:
- print("[WARNING] Running secondary value check with replacement of underscore in %s: %s" % (value, e))
if "_" in value:
value = value.replace("_", " ", -1)
elif " " in value:
@@ -2169,54 +2294,67 @@ class AppBase:
try:
if isinstance(basejson, list):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
return basejson, False
elif isinstance(basejson, bool):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (bool): %s" % value)
return basejson, False
elif isinstance(basejson, int):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (int): %s" % value)
return basejson, False
elif isinstance(basejson[value], str):
- print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value])
try:
- print("[DEBUG] BASEJSON: %s" % basejson)
if (basejson[value].endswith("}") and basejson[value].endswith("}")) or (basejson[value].startswith("[") and basejson[value].endswith("]")):
basejson = json.loads(basejson[value])
else:
- return str(basejson[value]), False
+
+ if outercnt == len(parsersplit)-1:
+ return str(basejson[value]), False
+ else:
+ pass
+
except json.decoder.JSONDecodeError as e:
- print("[DEBUG] RETURNING BECAUSE '%s' IS A NORMAL STRING (1)" % basejson[value])
return str(basejson[value]), False
else:
basejson = basejson[value]
-
except KeyError as e:
- print("\n\n[WARNING] Running third dot notation fix that always find the correct value %s: %s" % (value, e))
+ # Check if previous key was handled or not
+ previouskey = parsersplit[outercnt-1]
+
+ tmpval = previouskey + "." + value
+ if tmpval in basejson:
+ return basejson[tmpval], False
try:
currentsplitcnt = splitcnt
+
recursed_value = value
handled = False
+
+ #tmpbase = basejson
+ previouskey = value
while True:
newvalue = parsersplit[currentsplitcnt+1]
if newvalue == "#" or newvalue == "":
break
recursed_value += "." + newvalue
+
found = False
for key, value in basejson.items():
if recursed_value.lower() in key.lower():
found = True
if found == False:
- print("[INFO] DIDN'T FIND similar VALUE: ", recursed_value)
- break
+ # Check if we are on the last key or not
+ return "", False
if recursed_value in basejson:
- print("[INFO] FOUND RECURSED VALUE: ", recursed_value)
basejson = basejson[recursed_value]
- handled = True
+
+ # Whether to dig deeper or not
+ if isinstance(basejson, bool) or isinstance(basejson, int) or isinstance(basejson, str):
+ handled = False
+ else:
+ handled = True
+
break
currentsplitcnt += 1
@@ -2226,21 +2364,14 @@ class AppBase:
break
except IndexError as e:
- print("[DEBUG] INDEXERROR: ", parsersplit[outercnt])
- break
-
+ return "", False
outercnt += 1
-
+
except KeyError as e:
- print("[INFO] Lower keyerror: %s" % e)
return "", False
except Exception as e:
- print("[WARNING] Exception: %s" % e)
- return basejson, False
-
- #return basejson
- #return "KeyError: Couldn't find key: %s" % e
+ return "", False
return basejson, False
@@ -2256,7 +2387,6 @@ class AppBase:
baseresult = ""
appendresult = ""
- #print("[INFO] Parsersplit length: %d" % len(parsersplit))
if (actionname_lower.startswith("exec ") or actionname_lower.startswith("webhook ") or actionname_lower.startswith("schedule ") or actionname_lower.startswith("userinput ") or actionname_lower.startswith("email_trigger ") or actionname_lower.startswith("trigger ")) and len(parsersplit) == 1:
record = False
for char in actionname_lower:
@@ -2276,17 +2406,15 @@ class AppBase:
if actionname_lower == "exec" or actionname_lower == "webhook" or actionname_lower == "schedule" or actionname_lower == "userinput" or actionname_lower == "email_trigger" or actionname_lower == "trigger":
baseresult = execution_data["execution_argument"]
elif actionname_lower == "shuffle_cache":
- print("[DEBUG] SHOULD GET CACHE KEY: %s" % parsersplit)
if len(parsersplit) > 1:
actual_key = parsersplit[1]
- print("[DEBUG] KEY: %s" % actual_key)
cachedata = self.get_cache(actual_key)
- print("CACHE: %s" % cachedata)
parsersplit.pop(1)
try:
baseresult = json.dumps(cachedata)
except json.decoder.JSONDecodeError as e:
- print("[WARNING] Failed json dumping: %s" % e)
+ pass
+
else:
if execution_data["results"] != None:
@@ -2296,7 +2424,6 @@ class AppBase:
baseresult = result["result"]
break
else:
- print("[DEBUG] No results to get values from.")
baseresult = "$" + parsersplit[0][1:]
if len(baseresult) == 0:
@@ -2309,10 +2436,8 @@ class AppBase:
break
except KeyError as e:
- #print("[INFO] KeyError wf variables: %s" % e)
pass
except TypeError as e:
- #print("[INFO] TypeError wf variables: %s" % e)
pass
if len(baseresult) == 0:
@@ -2323,34 +2448,27 @@ class AppBase:
baseresult = variable["value"]
break
except KeyError as e:
- #print("[INFO] KeyError exec variables: %s" % e)
pass
except TypeError as e:
- #print("[INFO] TypeError exec variables: %s" % e)
pass
except KeyError as error:
- print(f"[DEBUG] KeyError in JSON: {error}")
-
- #print(f"[INFO] After first trycatch. Baseresult")#, baseresult)
+ pass
# 2. Find the JSON data
# Returns if there isn't any JSON in the base ($nodename)
if len(baseresult) == 0:
return ""+appendresult, False
- #print("[INFO] After second return")
# Returns if the result is JUST something like $nodename, not $nodename.value
if len(parsersplit) == 1:
returndata = str(baseresult)+str(appendresult)
- print("[DEBUG] RETURNING!")#: %s" % returndata)
return returndata, False
baseresult = baseresult.replace(" True,", " true,")
baseresult = baseresult.replace(" False", " false,")
# Tries to actually read it as JSON with some stupid formatting
- #print("[INFO] After third parser return - Formatted")#, baseresult)
basejson = {}
try:
basejson = json.loads(baseresult)
@@ -2359,10 +2477,8 @@ class AppBase:
baseresult = baseresult.replace("\'", "\"")
basejson = json.loads(baseresult)
except json.decoder.JSONDecodeError as e:
- print(f"[ERROR] Parser issue with JSON for {baseresult}: {e}")
return str(baseresult)+str(appendresult), False
- print("[INFO] After fourth parser return as JSON")
# Finds the ACTUAL value which is in the $nodename.value.test - focusing on value.test
data, is_loop = recurse_json(basejson, parsersplit[1:])
parseditem = data
@@ -2371,24 +2487,19 @@ class AppBase:
try:
parseditem = json.dumps(parseditem)
except json.decoder.JSONDecodeError as e:
- print("[WARNING] Parseditem issue: %s" % e)
pass
if is_loop:
- print("[DEBUG] DATA IS A LOOP - SHOULD WRAP")
if parsersplit[-1] == "#":
- print("[WARNING] SET DATA WRAPPER TO NORMAL!")
parseditem = "${SHUFFLE_NO_SPLITTER%s}$" % json.dumps(data)
else:
# Return value: ${id[12345, 45678]}$
- print("[WARNING] SET DATA WRAPPER TO %s!" % parsersplit[-1])
parseditem = "${%s%s}$" % (parsersplit[-1], json.dumps(data))
returndata = str(parseditem)+str(appendresult)
# New in 0.8.97: Don't return items without lists
- #self.logger.info("RETURNDATA: %s" % returndata)
#return returndata, is_loop
# 0.9.70:
@@ -2402,6 +2513,8 @@ class AppBase:
except json.decoder.JSONDecodeError as e:
return returndata, is_loop
+
+
# Sending self as it's not a normal function
def parse_liquid(template, self):
@@ -2413,21 +2526,26 @@ class AppBase:
return template
if "${" in template and "}$" in template:
- self.logger.info("[DEBUG] Shuffle loop shouldn't run in liquid. Data length: %d" % len(template))
+ #self.logger.info("[DEBUG] Shuffle loop shouldn't run in liquid. Data length: %d" % len(template))
return template
- #if not "{{" in template or not "}}" in template:
- # if not "{%" in template or not "%}" in template:
- # self.logger.info("Skipping liquid - missing {{ }} and {% %}")
- # return template
- #if not "{{" in template or not "}}" in template:
- # return template
+ # New pattern fixer to help with bad liquid formats
+ try:
+ newoutput = self.patternfix_string(template,
+ {
+ "{{|": '{{ "" |',
+ },
+ {
+ r'\{\{\s*\$[^|}]+\s*\|': '{{ "" |',
+ }
+ ,
+ inputtype="liquid"
+ )
- #self.logger.info(globals())
- #if len(template) > 100:
- # self.logger.info("[DEBUG] Running liquid with data of length %d" % len(template))
- #self.logger.info(f"[DEBUG] Data: {template}")
+ template = newoutput
+ except Exception as e:
+ print("[ERROR] Failed liquid parsing fix: %s" % e)
all_globals = globals()
all_globals["self"] = self
@@ -2488,7 +2606,6 @@ class AppBase:
newlines = []
thisline = []
for line in template.split("\n"):
- #print("LINE: %s" % repr(line))
if "\"\"\"" in line or "\'\'\'" in line:
if replace:
skip_next = True
@@ -2499,7 +2616,6 @@ class AppBase:
thisline.append(line)
if skip_next == True:
if len(thisline) > 0:
- #print(thisline)
newlines.append(" ".join(thisline))
thisline = []
@@ -2524,7 +2640,6 @@ class AppBase:
except TypeError as e:
try:
if "string as left operand" in f"{e}":
- #print(f"HANDLE REPLACE: {template}")
split_left = template.split("|")
if len(split_left) < 2:
return template
@@ -2544,8 +2659,6 @@ class AppBase:
return run.render(**globals())
except Exception as e:
- print(f"SubError in Liquid: {e}")
-
self.action["parameters"].append({
"name": "liquid_general_error",
"value": f"There was general error Liquid input (2). Details: {e}",
@@ -2586,7 +2699,6 @@ class AppBase:
self.action_result["result"] = json.dumps(data)
except Exception as e:
self.action_result["result"] = f"Failed to parse LiquidPy: {error_msg}"
- print("[WARNING] Failed to set LiquidPy result")
self.action_result["completed_at"] = int(time.time_ns())
self.send_result(self.action_result, headers, stream_path)
@@ -2620,15 +2732,12 @@ class AppBase:
try:
value = json.dumps(value)
except:
- print("[WARNING] Json parsing issue in recursed value")
pass
if value == "${%s}" % key:
- print("[WARNING] Deleting %s because key = value" % key)
deletekeys.append(key)
continue
elif "${" in value and "}" in value:
- print("[WARNING] Deleting %s because it contains ${ and }" % key)
deletekeys.append(key)
continue
@@ -2638,9 +2747,9 @@ class AppBase:
except json.decoder.JSONDecodeError as e:
# Since here the data isn't at all JSON compatible..?
# Seems to happen with newlines in variables being parsed in as strings?
- print(f"[ERROR] Failed JSON replacement for OpenAPI keys (3) {e}. Value: {data}")
+ pass
except Exception as e:
- print(f"[ERROR] Failed as an exception (1): {e}")
+ pass
try:
for deletekey in deletekeys:
@@ -2649,7 +2758,6 @@ class AppBase:
except:
pass
except Exception as e:
- print(f"[WARNING] Failed in deletekeys: {e}")
return data
try:
@@ -2670,13 +2778,12 @@ class AppBase:
try:
data = json.dumps(newvalue)
except json.decoder.JSONDecodeError as e:
- print("[WARNING] JsonDecodeError: %s" % e)
data = newvalue
except json.decoder.JSONDecodeError as e:
- print("[WARNING] Failed JSON replacement for OpenAPI keys (2) {e}")
+ pass
except Exception as e:
- print(f"[WARNING] Failed as an exception (2): {e}")
+ pass
return data
@@ -2695,7 +2802,7 @@ class AppBase:
value = value.replace("\\\'", "\'")
value = value.replace("\'", "\\\'")
except Exception as e:
- print(f"[WARNING] Failed to fix json string value: {e}")
+ pass
return value
@@ -2713,7 +2820,8 @@ class AppBase:
#match = ".*?([$]{1}([a-zA-Z0-9 _-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,})"
#match = ".*?([$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,})" # Removed space - no longer ok. Force underscore.
- match = "([$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,})" # Removed .*? to make it work with large amounts of data
+ #match = "([$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,})" # Removed .*? to make it work with large amounts of data
+ match = "([$]{1}([a-zA-Z0-9_@-]+\.?){1}([a-zA-Z0-9#_@-]+\.?){0,})" # Added @ to the regex
# Extra replacements for certain scenarios
escaped_dollar = "\\$"
@@ -2735,7 +2843,6 @@ class AppBase:
# Basic fix in case variant isn't set
# Variant is ALWAYS STATIC_VALUE from mid 2021~
try:
- #self.logger.info(f"[DEBUG] Parameter '{paramname}' of length {len(parameter['value'])}")
parameter["variant"] = parameter["variant"]
except:
parameter["variant"] = "STATIC_VALUE"
@@ -2760,8 +2867,9 @@ class AppBase:
# Handles for loops etc.
# FIXME: Should it dump to string here? Doesn't that defeat the purpose?
# Trying without string dumping.
-
+ #self.logger.info("TO BE REPLACED: %s" % to_be_replaced)
value, is_loop = get_json_value(fullexecution, to_be_replaced)
+
#self.logger.info(f"\n\nType of value: {type(value)}")
if isinstance(value, str):
# Could we take it here?
@@ -2772,32 +2880,30 @@ class AppBase:
# 2. Check if there is a quote infront of it and also if there are {} in the data to validate JSON
# 3. If there are, sanitize!
#if data.find(f'"{to_be_replaced}"') != -1 and data.find("{") != -1 and data.find("}") != -1:
- # print(f"[DEBUG] Found quotes infront of and after {to_be_replaced}! This probably means it's JSON and should be sanitized.")
# returnvalue = fix_json_string_value(value)
# value = returnvalue
-
- parameter["value"] = parameter["value"].replace(to_be_replaced, value)
+ parameter["value"] = parameter["value"].replace(to_be_replaced, value, 1)
elif isinstance(value, dict) or isinstance(value, list):
# Changed from JSON dump to str() 28.05.2021
# This makes it so the parameters gets lists and dicts straight up
- parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value))
+ parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value), 1)
#try:
- # parameter["value"] = parameter["value"].replace(to_be_replaced, str(value))
- #except:
# parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value))
+ #except:
+ # parameter["value"] = parameter["value"].replace(to_be_replaced, str(value))
# self.logger.info("Failed parsing value as string?")
else:
self.logger.error("[ERROR] Unknown type %s" % type(value))
try:
- parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value))
+ parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value), 1)
except json.decoder.JSONDecodeError as e:
- parameter["value"] = parameter["value"].replace(to_be_replaced, value)
+ parameter["value"] = parameter["value"].replace(to_be_replaced, value, 1)
- #self.logger.info("VALUE: %s" % parameter["value"])
else:
- self.logger.info(f"[ERROR] Not running static variant regex parsing (slow) on value with length {len(parameter['value'])}. Max is 5Mb~.")
+ #self.logger.info(f"[ERROR] Not running static variant regex parsing (slow) on value with length {len(parameter['value'])}. Max is 5Mb~.")
+ pass
if parameter["variant"] == "WORKFLOW_VARIABLE":
self.logger.info("[DEBUG] Handling workflow variable")
@@ -2896,7 +3002,7 @@ class AppBase:
return "", parameter["value"], is_loop
def run_validation(sourcevalue, check, destinationvalue):
- self.logger.info("[DEBUG] Checking %s '%s' %s" % (sourcevalue, check, destinationvalue))
+ #self.logger.info("[DEBUG] Checking %s '%s' %s" % (sourcevalue, check, destinationvalue))
if check == "=" or check.lower() == "equals":
if str(sourcevalue).lower() == str(destinationvalue).lower():
@@ -2936,7 +3042,6 @@ class AppBase:
continue
if item.strip() in sourcevalue:
- print("[INFO] Found %s in %s" % (item, sourcevalue))
return True
elif check.lower() == "larger than" or check.lower() == "bigger than":
@@ -2969,7 +3074,7 @@ class AppBase:
return True
except AttributeError as e:
- print("[WARNING] Condition smaller than failed with values %s and %s: %s" % (sourcevalue, destinationvalue, e))
+ pass
try:
destinationvalue = len(json.loads(destinationvalue))
@@ -2987,10 +3092,8 @@ class AppBase:
try:
found = re.search(str(destinationvalue), str(sourcevalue))
except re.error as e:
- print("[WARNING] Regex error in condition (re.error): %s" % e)
return False
except Exception as e:
- print("[WARNING] Regex error in condition (catchall): %s" % e)
return False
if found == None:
@@ -3017,30 +3120,6 @@ class AppBase:
if action["id"] == fullexecution["start"]:
return True, ""
- # Need to validate if the source is a trigger or not
- # need to remove branches that are not from trigger to the startnode to make it all work
- #if "workflow" in fullexecution["workflow"] and "triggers" in fullexecution["workflow"]:
- # cnt = 0
- # found_branch_indexes = []
- # for branch in fullexecution["workflow"]["branches"]:
- # if branch["destination_id"] != action["id"]:
- # continue
-
- # # Check if the source is a trigger
- # # if we can't find it as trigger, remove the branch
- # print("Found relevant branch: %s" % branch)
- # for action in fullexecution["workflow"]["actions"]:
- # if action["id"] == branch["source_id"]:
- # found_branch_indexes.append(branch["source_id"])
- # break
-
- # if len(found_branch_indexes) > 0:
- # for i in sorted(found_branch_indexes, reverse=True):
- # fullexecution["workflow"]["branches"].pop(i)
-
- # print("Removed %d branches" % len(found_branch_indexes))
- #else:
- # print("[WARNING] No branches or triggers found in fullexecution for startnode")
except Exception as error:
self.logger.info(f"[WARNING] Failed checking startnode: {error}")
#return True, ""
@@ -3106,8 +3185,6 @@ class AppBase:
successful_conditions = 0
total_conditions = len(branch["conditions"])
for condition in branch["conditions"]:
- self.logger.info("[DEBUG] Getting condition value of %s" % condition)
-
# Parse all values first here
sourcevalue = condition["source"]["value"]
check, sourcevalue, is_loop = parse_params(action, fullexecution, condition["source"], self)
@@ -3147,7 +3224,7 @@ class AppBase:
if matching_branches > 0 and correct_branches > 0:
return True, ""
- self.logger.info("[DEBUG] Correct branches vs matching branches: %d vs %d" % (correct_branches, matching_branches))
+ #self.logger.info("[DEBUG] Correct branches vs matching branches: %d vs %d" % (correct_branches, matching_branches))
return False, {"success": False, "reason": "Minimum of one branch's conditions must be correct to continue. Total: %d of %d" % (correct_branches, matching_branches)}
@@ -3182,11 +3259,11 @@ class AppBase:
#tmpresult = tmpresult.replace("'", "\"")
tmpresult = json.dumps(tmpresult)
except json.decoder.JSONDecodeError as e:
- self.logger.info(f"[WARNING] Failed condition parsing {tmpresult} to string")
+ pass
+
# IF branches fail: Exit!
if not branchcheck:
- self.logger.info("Failed one or more branch conditions.")
self.action_result["result"] = tmpresult
self.action_result["status"] = "SKIPPED"
self.action_result["completed_at"] = int(time.time_ns())
@@ -3200,8 +3277,6 @@ class AppBase:
if " " in actionname:
actionname.replace(" ", "_", -1)
- #print("ACTION: ", action)
- #print("exec: ", self.full_execution)
#if action.generated:
# actionname = actionname.lower()
@@ -3229,14 +3304,6 @@ class AppBase:
# What variables are necessary here tho hmm
params = {}
- # This replacement should happen in backend as part of params
- # error log is useless
- #try:
- # for item in action["authentication"]:
- # self.logger.info("AUTH PARAM: ", key, value)
- # #params[item["key"]] = item["value"]
- #except KeyError as e:
- # self.logger.info(f"[WARNING] No authentication specified! Is this correct? err: {e}")
# Fixes OpenAPI body parameters for later.
newparams = []
@@ -3265,9 +3332,7 @@ class AppBase:
# but this has changed to do lists within items and such
if parameter["name"] == "body":
bodyindex = counter
- #self.logger.info("PARAM: %s" % parameter)
- # FIXMe: This should also happen after liquid & param parsing..
try:
values = parameter["value_replace"]
if values != None:
@@ -3307,7 +3372,6 @@ class AppBase:
pass
- #self.logger.info(f"""HANDLING BODY: {action["parameters"][counter]["value"]}""")
action["parameters"][counter]["value"] = recurse_cleanup_script(action["parameters"][counter]["value"])
#self.logger.info(action["parameters"])
@@ -3322,7 +3386,7 @@ class AppBase:
try:
self.original_action = json.loads(json.dumps(action))
except Exception as e:
- self.logger.info(f"[ERROR] Failed parsing action as JSON to original action. This COULD have bad effects on LOOPED executions: {e}")
+ pass
# calltimes is used to handle forloops in the app itself.
# 2 kinds of loop - one in gui with one app each, and one like this,
@@ -3343,8 +3407,8 @@ class AppBase:
if check:
raise Exception(json.dumps({
"success": False,
- "reason": "Parameter {parameter} has an issue",
"exception": f"Value Error: {check}",
+ "reason": "Parameter {parameter} has an issue",
}))
#if parameter["name"] == "body":
@@ -3364,227 +3428,111 @@ class AppBase:
except KeyError:
pass
- #self.logger.info("Return value: %s" % value)
actionname = action["name"]
- #self.logger.info("Multicheck ", actualitem)
- #self.logger.info("ITEM LENGTH: %d, Actual item: %s" % (len(actualitem), actualitem))
+
+ # Loops in general goes in here to be parsed out as one->multi
if len(actualitem) > 0:
multiexecution = True
- # Loop WITHOUT JSON variables go here.
- # Loop WITH variables go in else.
- self.logger.info("Before first part in multiexec!")
handled = False
# Has a loop without a variable used inside
- if len(actualitem[0]) > 2 and actualitem[0][1] == "SHUFFLE_NO_SPLITTER":
-
- self.logger.info("(1) Pre replacement: %s" % actualitem[0][2])
- tmpitem = value
-
- index = 0
- replacement = actualitem[index][2]
- if replacement.endswith("}$"):
- replacement = replacement[:-2]
-
- if replacement.startswith("\"") and replacement.endswith("\""):
- replacement = replacement[1:len(replacement)-1]
-
- self.logger.info("POST replacement: %s" % replacement)
-
- #json_replacement = tmpitem.replace(actualitem[index][0], replacement, 1)
- #self.logger.info("AFTER POST replacement: %s" % json_replacement)
- json_replacement = replacement
+
+ # This is here to handle for loops within variables.. kindof
+ # 1. Find the length of the longest array
+ # 2. Build an array with the base values based on parameter["value"]
+ # 3. Get the n'th value of the generated list from values
+ # 4. Execute all n answers
+ replacements = {}
+ curminlength = 0
+ for replace in actualitem:
try:
- json_replacement = json.loads(replacement)
+ to_be_replaced = replace[0]
+ actualitem = replace[2]
+ if actualitem.endswith("}$"):
+ actualitem = actualitem[:-2]
+
+ except IndexError:
+ self.logger.info("[WARNING] Indexerror")
+ continue
+
+ try:
+ itemlist = json.loads(actualitem)
+ if len(itemlist) > minlength:
+ minlength = len(itemlist)
+
+ if len(itemlist) > curminlength:
+ curminlength = len(itemlist)
+
except json.decoder.JSONDecodeError as e:
+ self.logger.info("JSON Error (replace): %s in %s" % (e, actualitem))
+
+ replacements[to_be_replaced] = actualitem
+
+
+ # Parses the data as string with length, split etc. before moving on.
+ #self.logger.info("In second part of else: %s" % (len(itemlist)))
+ # This is a result array for JUST this value..
+ # What if there are more?
+ resultarray = []
+ for i in range(0, curminlength):
+ tmpitem = json.loads(json.dumps(parameter["value"]))
+ for key, value in replacements.items():
+ replacement = value
try:
- replacement = replacement.replace("\'", "\"", -1)
- json_replacement = json.loads(replacement)
- except:
- self.logger.info("JSON error singular: %s" % e)
+ replacement = json.dumps(json.loads(value)[i])
+ except IndexError as e:
+ self.logger.info(f"[ERROR] Failed handling value parsing with index: {e}")
+ pass
- if len(json_replacement) > minlength:
- minlength = len(json_replacement)
+ if replacement.startswith("\"") and replacement.endswith("\""):
+ replacement = replacement[1:len(replacement)-1]
- self.logger.info("PRE new_replacement")
-
- new_replacement = []
- for i in range(len(json_replacement)):
- if isinstance(json_replacement[i], dict) or isinstance(json_replacement[i], list):
- tmp_replacer = json.dumps(json_replacement[i])
- newvalue = tmpitem.replace(str(actualitem[index][0]), str(tmp_replacer), 1)
- else:
- newvalue = tmpitem.replace(str(actualitem[index][0]), str(json_replacement[i]), 1)
+ #except json.decoder.JSONDecodeError as e:
+ #self.logger.info("REPLACING %s with %s" % (key, replacement))
+ #replacement = parse_wrapper_start(replacement)
+ tmpitem = tmpitem.replace(key, replacement, -1)
try:
- newvalue = parse_liquid(newvalue, self)
+ tmpitem = parse_liquid(tmpitem, self)
except Exception as e:
self.logger.info(f"[WARNING] Failed liquid parsing in loop (2): {e}")
- try:
- newvalue = json.loads(newvalue)
- except json.decoder.JSONDecodeError as e:
- self.logger.info("DECODER ERROR: %s" % e)
- pass
-
- new_replacement.append(newvalue)
-
- self.logger.info("New replacement: %s" % new_replacement)
-
- # FIXME: Should this use new_replacement?
- tmpitem = tmpitem.replace(actualitem[index][0], replacement, 1)
# This code handles files.
- resultarray = []
isfile = False
try:
- self.logger.info("(1) ------------ PARAM: %s" % parameter["schema"]["type"])
if parameter["schema"]["type"] == "file" and len(value) > 0:
- self.logger.info("(1) SHOULD HANDLE FILE IN MULTI. Get based on value %s" % tmpitem)
- # This is silly :)
- # Q: Is there something wrong with the download system?
- # It seems to return "FILE CONTENT: %s" with the ID as %s
- for tmp_file_split in json.loads(tmpitem):
- self.logger.info("(1) PRE GET FILE %s" % tmp_file_split)
+ self.logger.info("(2) SHOULD HANDLE FILE IN MULTI. Get based on value %s" % parameter["value"])
+
+ for tmp_file_split in json.loads(parameter["value"]):
file_value = self.get_file(tmp_file_split)
- self.logger.info("(1) POST AWAIT %s" % file_value)
resultarray.append(file_value)
- self.logger.info("(1) FILE VALUE FOR VAL %s: %s" % (tmp_file_split, file_value))
+
isfile = True
- except NameError as e:
- self.logger.info("(1) SCHEMA NAMEERROR IN FILE HANDLING: %s" % e)
except KeyError as e:
- self.logger.info("(1) SCHEMA KEYERROR IN FILE HANDLING: %s" % e)
+ self.logger.info("(2) SCHEMA ERROR IN FILE HANDLING: %s" % e)
except json.decoder.JSONDecodeError as e:
- self.logger.info("(1) JSON ERROR IN FILE HANDLING: %s" % e)
+ self.logger.info("(2) JSON ERROR IN FILE HANDLING: %s" % e)
if not isfile:
- self.logger.info("Resultarray (NOT FILE): %s" % resultarray)
- params[parameter["name"]] = tmpitem
- multi_parameters[parameter["name"]] = new_replacement
- else:
- self.logger.info("Resultarray (FILE): %s" % resultarray)
- params[parameter["name"]] = resultarray
- multi_parameters[parameter["name"]] = resultarray
+ #tmpitem = tmpitem.replace("\\\\", "\\", -1)
+ resultarray.append(tmpitem)
- #if len(resultarray) == 0:
- # self.logger.info("[WARNING] Returning empty array because the array length to be looped is 0 (1)")
- # action_result["status"] = "SUCCESS"
- # action_result["result"] = "[]"
- # self.send_result(action_result, headers, stream_path)
- # return
+ # With this parameter ready, add it to... a greater list of parameters. Rofl
+ if len(resultarray) == 0:
+ self.logger.info("[WARNING] Returning empty array because the array length to be looped is 0 (0)")
+ self.action_result["status"] = "SUCCESS"
+ self.action_result["result"] = "[]"
+ self.send_result(self.action_result, headers, stream_path)
+ return
- multi_execution_lists.append(new_replacement)
- #self.logger.info("MULTI finished: %s" % json_replacement)
- else:
- self.logger.info(f"(2) Pre replacement (loop with variables). Variables: {actualitem}") #% actualitem)
- # This is here to handle for loops within variables.. kindof
- # 1. Find the length of the longest array
- # 2. Build an array with the base values based on parameter["value"]
- # 3. Get the n'th value of the generated list from values
- # 4. Execute all n answers
- replacements = {}
- curminlength = 0
- for replace in actualitem:
- try:
- to_be_replaced = replace[0]
- actualitem = replace[2]
- if actualitem.endswith("}$"):
- actualitem = actualitem[:-2]
+ #self.logger.info("RESULTARRAY: %s" % resultarray)
+ if resultarray not in multi_execution_lists:
+ multi_execution_lists.append(resultarray)
- except IndexError:
- self.logger.info("[WARNING] Indexerror")
- continue
-
- #self.logger.info(f"\n\nTMPITEM: {actualitem}\n\n")
- #actualitem = parse_wrapper_start(actualitem)
- #self.logger.info(f"\n\nTMPITEM2: {actualitem}\n\n")
-
- try:
- itemlist = json.loads(actualitem)
- if len(itemlist) > minlength:
- minlength = len(itemlist)
-
- if len(itemlist) > curminlength:
- curminlength = len(itemlist)
-
- except json.decoder.JSONDecodeError as e:
- self.logger.info("JSON Error (replace): %s in %s" % (e, actualitem))
-
- replacements[to_be_replaced] = actualitem
-
-
- # Parses the data as string with length, split etc. before moving on.
-
-
- #self.logger.info("In second part of else: %s" % (len(itemlist)))
- # This is a result array for JUST this value..
- # What if there are more?
- resultarray = []
- for i in range(0, curminlength):
- tmpitem = json.loads(json.dumps(parameter["value"]))
- for key, value in replacements.items():
- replacement = value
- try:
- replacement = json.dumps(json.loads(value)[i])
- except IndexError as e:
- self.logger.info(f"[ERROR] Failed handling value parsing with index: {e}")
- pass
-
- if replacement.startswith("\"") and replacement.endswith("\""):
- replacement = replacement[1:len(replacement)-1]
- #except json.decoder.JSONDecodeError as e:
-
- #self.logger.info("REPLACING %s with %s" % (key, replacement))
- #replacement = parse_wrapper_start(replacement)
- tmpitem = tmpitem.replace(key, replacement, -1)
- try:
- tmpitem = parse_liquid(tmpitem, self)
- except Exception as e:
- self.logger.info(f"[WARNING] Failed liquid parsing in loop (2): {e}")
-
-
- # This code handles files.
- self.logger.info("(2) ------------ PARAM: %s" % parameter["schema"]["type"])
- isfile = False
- try:
- if parameter["schema"]["type"] == "file" and len(value) > 0:
- self.logger.info("(2) SHOULD HANDLE FILE IN MULTI. Get based on value %s" % parameter["value"])
-
- for tmp_file_split in json.loads(parameter["value"]):
- self.logger.info("(2) PRE GET FILE %s" % tmp_file_split)
- file_value = self.get_file(tmp_file_split)
- self.logger.info("(2) POST AWAIT %s" % file_value)
- resultarray.append(file_value)
- self.logger.info("(2) FILE VALUE FOR VAL %s: %s" % (tmp_file_split, file_value))
-
-
- isfile = True
- except KeyError as e:
- self.logger.info("(2) SCHEMA ERROR IN FILE HANDLING: %s" % e)
- except json.decoder.JSONDecodeError as e:
- self.logger.info("(2) JSON ERROR IN FILE HANDLING: %s" % e)
-
- if not isfile:
- tmpitem = tmpitem.replace("\\\\", "\\", -1)
- resultarray.append(tmpitem)
-
- # With this parameter ready, add it to... a greater list of parameters. Rofl
- self.logger.info("LENGTH OF ARR: %d" % len(resultarray))
- if len(resultarray) == 0:
- self.logger.info("[WARNING] Returning empty array because the array length to be looped is 0 (0)")
- self.action_result["status"] = "SUCCESS"
- self.action_result["result"] = "[]"
- self.send_result(self.action_result, headers, stream_path)
- return
-
- #self.logger.info("RESULTARRAY: %s" % resultarray)
- if resultarray not in multi_execution_lists:
- multi_execution_lists.append(resultarray)
-
- multi_parameters[parameter["name"]] = resultarray
+ multi_parameters[parameter["name"]] = resultarray
else:
# Parses things like int(value)
#self.logger.info("[DEBUG] Normal parsing (not looping)")#with data %s" % value)
@@ -3596,7 +3544,7 @@ class AppBase:
if str(value).startswith("b'") and str(value).endswith("'"):
value = value[2:-1]
except Exception as e:
- print(f"Value rawbytes Exception: {e}")
+ pass
params[parameter["name"]] = value
multi_parameters[parameter["name"]] = value
@@ -3613,13 +3561,11 @@ class AppBase:
except KeyError as e:
self.logger.info("SCHEMA ERROR IN FILE HANDLING: %s" % e)
-
- #remove_params.append(parameter["name"])
+
# Fix lists here
# FIXME: This doesn't really do anything anymore
- self.logger.info("[DEBUG] CHECKING multi execution list: %d!" % len(multi_execution_lists))
+ #self.logger.info("[DEBUG] CHECKING multi execution list: %d!" % len(multi_execution_lists))
if len(multi_execution_lists) > 0:
- self.logger.info("\n [DEBUG] Multi execution list has more data: %d" % len(multi_execution_lists))
filteredlist = []
for listitem in multi_execution_lists:
if listitem in filteredlist:
@@ -3668,18 +3614,17 @@ class AppBase:
if not multiexecution:
# Runs a single iteration here
new_params = self.validate_unique_fields(params)
- self.logger.info(f"[DEBUG] Returned with newparams of length {len(new_params)}")
if isinstance(new_params, list) and len(new_params) == 1:
params = new_params[0]
else:
- self.logger.info("[WARNING] SHOULD STOP EXECUTION BECAUSE FIELDS AREN'T UNIQUE")
+ #self.logger.info("[WARNING] SHOULD STOP EXECUTION BECAUSE FIELDS AREN'T UNIQUE")
self.action_result["status"] = "SKIPPED"
self.action_result["result"] = f"A non-unique value was found"
self.action_result["completed_at"] = int(time.time_ns())
self.send_result(self.action_result, headers, stream_path)
return
- self.logger.info("[INFO] Running normal execution (not loop)\n\n")
+ #self.logger.info("[INFO] Running normal execution (not loop)\n\n")
# Added literal evaluation of anything resembling a string
# The goal is to parse objects that e.g. use single quotes and the like
@@ -3742,6 +3687,7 @@ class AppBase:
self.logger.info(f"[ERROR] Failed parsing timeout to int: {e}")
#timeout = 30
+ self.logger.info("[DEBUG][%s] Running function '%s' with timeout %d" % (self.current_execution_id, action["name"], timeout))
try:
executor = concurrent.futures.ThreadPoolExecutor()
@@ -3753,20 +3699,19 @@ class AppBase:
future.cancel()
newres = json.dumps({
"success": False,
- "reason": "Timeout error within %d seconds (1). This happens if we can't reach or use the API you're trying to use within the time limit. Configure SHUFFLE_APP_SDK_TIMEOUT=100 in Orborus to increase it to 100 seconds. Not changeable for cloud." % timeout,
"exception": str(e),
+ "reason": "Timeout error within %d seconds (1). This happens if we can't reach or use the API you're trying to use within the time limit. Configure SHUFFLE_APP_SDK_TIMEOUT=100 in Orborus to increase it to 100 seconds. Not changeable for cloud." % timeout,
})
else:
# The future is done, so we can just get the result from newres :)
#newres = future.result()
- #print("Future is done!")
pass
except concurrent.futures.TimeoutError as e:
newres = json.dumps({
"success": False,
- "reason": "Timeout error within %d seconds (2). This happens if we can't reach or use the API you're trying to use within the time limit. Configure SHUFFLE_APP_SDK_TIMEOUT=100 in Orborus to increase it to 100 seconds. Not changeable for cloud." % timeout,
+ "reason": "Timeout error (2) within %d seconds (2). This happens if we can't reach or use the API you're trying to use within the time limit. Configure SHUFFLE_APP_SDK_TIMEOUT=100 in Orborus to increase it to 100 seconds. Not changeable for cloud." % timeout,
})
break
@@ -3786,8 +3731,8 @@ class AppBase:
newres = json.dumps({
"success": False,
- "reason": "An exception occurred while running this function (1). See exception for more details and contact support if this persists (support@shuffler.io)",
"exception": f"{type(e).__name__} - {e}",
+ "reason": "An exception occurred while running this function (1). See exception for more details and contact support if this persists (support@shuffler.io)",
})
break
elif "got an unexpected keyword argument" in errorstring:
@@ -3803,8 +3748,8 @@ class AppBase:
else:
newres = json.dumps({
"success": False,
- "reason": "You may be running an old version of this action. Try remaking the node, then contact us at support@shuffler.io if it doesn't work with all these details.",
"exception": f"TypeError: {e}",
+ "reason": "You may be running an old version of this action. Try remaking the node, then contact us at support@shuffler.io if it doesn't work with all these details.",
})
break
except Exception as e:
@@ -3817,8 +3762,8 @@ class AppBase:
newres = json.dumps({
"success": False,
- "reason": "An exception occurred while running this function (2). See exception for more details and contact support if this persists (support@shuffler.io)",
"exception": f"{type(e).__name__} - {e}",
+ "reason": "An exception occurred while running this function (2). See exception for more details and contact support if this persists (support@shuffler.io)",
})
break
@@ -3841,14 +3786,13 @@ class AppBase:
except Exception as e:
self.logger.warning("[ERROR] Failed to parse coroutine value for old app: {e}")
- self.logger.info("\n\n\n[INFO] Returned from execution with type(s) %s" % type(newres))
+ #self.logger.info("\n\n\n[INFO] Returned from execution with type(s) %s" % type(newres))
#self.logger.info("\n[INFO] Returned from execution with %s of types %s" % (newres, type(newres)))#, newres)
if isinstance(newres, tuple):
- self.logger.info(f"[INFO] Handling return as tuple: {newres}")
+ #self.logger.info(f"[INFO] Handling return as tuple: {newres}")
# Handles files.
filedata = ""
file_ids = []
- self.logger.info("TUPLE: %s" % newres[1])
if isinstance(newres[1], list):
self.logger.info("[INFO] HANDLING LIST FROM RET")
file_ids = self.set_files(newres[1])
@@ -3869,7 +3813,7 @@ class AppBase:
result = json.dumps(tmp_result)
elif isinstance(newres, str):
- self.logger.info("[INFO] Handling return as string of length %d" % len(newres))
+ #self.logger.info("[INFO] Handling return as string of length %d" % len(newres))
result += newres
elif isinstance(newres, dict) or isinstance(newres, list):
try:
@@ -3880,7 +3824,7 @@ class AppBase:
result += str(newres)
except ValueError:
result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres)
- self.logger.info("Can't handle type %s value from function" % (type(newres)))
+ self.logger.info("[ERROR] Can't handle type %s value from function" % (type(newres)))
except Exception as e:
self.logger.info("[ERROR] Failed to json dump. Returning as string.")
result += str(newres)
@@ -3891,13 +3835,13 @@ class AppBase:
result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres)
self.logger.info("Can't handle type %s value from function" % (type(newres)))
- #self.logger.info("[INFO] POST NEWRES RESULT!")#, result)
else:
#self.logger.info("[INFO] APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters))
# 1. Use number of executions based on the arrays being similar
# 2. Find the right value from the parsed multi_params
- self.logger.info("[INFO] Running WITHOUT outer loop (looping)")
+ #self.logger.info("[INFO] Running WITH loop. MULTI: %s", multi_parameters)
+ self.logger.info("[INFO] Running WITH loop")
json_object = False
#results = await self.run_recursed_items(func, multi_parameters, {})
results = self.run_recursed_items(func, multi_parameters, {})
@@ -3907,7 +3851,6 @@ class AppBase:
# Dump the result as a string of a list
#self.logger.info("RESULTS: %s" % results)
if isinstance(results, list) or isinstance(results, dict):
- self.logger.info(f"JSON OBJECT? {json_object}")
# This part is weird lol
if json_object:
@@ -3946,7 +3889,7 @@ class AppBase:
if self.action_result["result"] == "":
self.action_result["result"] = result
- self.logger.debug(f"[DEBUG] Executed {action['label']}-{action['id']}")#with result: {result}")
+ #self.logger.debug(f"[DEBUG] Executed {action['label']}-{action['id']}")#with result: {result}")
#self.logger.debug(f"Data: %s" % action_result)
except TypeError as e:
self.logger.info("[ERROR] TypeError issue: %s" % e)
@@ -4025,16 +3968,16 @@ class AppBase:
logger = logging.getLogger(f"{cls.__name__}")
logger.setLevel(logging.DEBUG)
- logger.info("[DEBUG] Normal execution.")
+ #logger.info("[DEBUG] Normal execution.")
##############################################
exposed_port = os.getenv("SHUFFLE_APP_EXPOSED_PORT", "")
- logger.info(f"[DEBUG] \"{runtime}\" - run indicates microservices. Port: \"{exposed_port}\"")
+ #logger.info(f"[DEBUG] \"{runtime}\" - run indicates microservices. Port: \"{exposed_port}\"")
if runtime == "run" and exposed_port != "":
# Base port is 33334. Exposed port may differ based on discovery from Worker
port = int(exposed_port)
- logger.info(f"[DEBUG] Starting webserver on port {port} (same as exposed port)")
+ #logger.info(f"[DEBUG] Starting webserver on port {port} (same as exposed port)")
from flask import Flask, request
from waitress import serve
@@ -4049,7 +3992,6 @@ class AppBase:
@flask_app.route("/api/v1/run", methods=["POST"])
def execute():
if request.method == "POST":
- #print(request.get_json(force=True))
requestdata = {}
try:
requestdata = json.loads(request.data)
@@ -4059,8 +4001,6 @@ class AppBase:
"reason": f"Invalid Action data {e}",
}
- #logger.info(f"[DEBUG] Datatype: {type(requestdata)}: {requestdata}")
-
# Remaking class for each request
app = cls(redis=None, logger=logger, console_logger=logger)
@@ -4071,41 +4011,33 @@ class AppBase:
try:
app.full_execution = json.dumps(requestdata["workflow_execution"])
except Exception as e:
- logger.info(f"[ERROR] Failed parsing full execution from workflow_execution: {e}")
extra_info += f"\n{e}"
try:
app.action = requestdata["action"]
except Exception as e:
- logger.info(f"[ERROR] Failed parsing action: {e}")
extra_info += f"\n{e}"
try:
app.authorization = requestdata["authorization"]
app.current_execution_id = requestdata["execution_id"]
except Exception as e:
- logger.info(f"[ERROR] Failed parsing auth and exec id: {e}")
extra_info += f"\n{e}"
# BASE URL (backend)
try:
app.url = requestdata["url"]
- logger.info(f"BACKEND URL (url): {app.url}")
except Exception as e:
- logger.info(f"[ERROR] Failed parsing url (backend): {e}")
extra_info += f"\n{e}"
# URL (worker)
try:
app.base_url = requestdata["base_url"]
- logger.info(f"WORKER URL (base url): {app.base_url}")
except Exception as e:
- logger.info(f"[ERROR] Failed parsing base url (worker): {e}")
extra_info += f"\n{e}"
#await
app.execute_action(app.action)
- logger.info("[DEBUG] Done awaiting app action running")
except Exception as e:
return {
"success": False,
@@ -4148,12 +4080,12 @@ class AppBase:
# Has to start like this due to imports in other apps
# Move it outside everything?
app = cls(redis=None, logger=logger, console_logger=logger)
- #logger.info(f"[DEBUG] Action: {action}")
if isinstance(action, str):
- logger.info("[DEBUG] Normal execution (env var). Action is a string.")
+ #logger.info("[DEBUG] Normal execution (env var). Action is a string.")
+ pass
elif isinstance(action, object):
- logger.info("[DEBUG] OBJECT execution (cloud). Action is NOT a string.")
+ #logger.info("[DEBUG] OBJECT execution (cloud). Action is NOT a string.")
app.action = action
try:
@@ -4174,7 +4106,8 @@ class AppBase:
except:
pass
else:
- self.logger.info("ACTION TYPE (unhandled): %s" % type(action))
+ #self.logger.info("ACTION TYPE (unhandled): %s" % type(action))
+ pass
app.execute_action(app.action)
diff --git a/backend/app_sdk/autocorrect_test.py b/backend/app_sdk/autocorrect_test.py
new file mode 100644
index 00000000..a7624c76
--- /dev/null
+++ b/backend/app_sdk/autocorrect_test.py
@@ -0,0 +1,187 @@
+import re
+import json
+
+input_data = """{
+ "test4": $test,
+ "test5": ,
+ "test6": "what"
+ }
+"""
+
+input_data = """{
+ "test0": {{ '' | default: [] }},
+ "test": {{ | default: [] }},
+ "test2": {{ $test.asd | default: [] }},
+ "test3": {{ {"key": "val} | default: [] }},
+ "test4": $test,
+ "test5": ,
+ "test6": "what"
+ }
+"""
+
+
+liquiddata = "{{ $test.asd | some other stuff {{ $test.xyz | more stuff"
+pattern = r'\{\{\s*\$[^|}]+\s*\|'
+
+replaced_data = re.sub(pattern, "{{ '' |", liquiddata)
+print(replaced_data)
+
+
+def patternfix_string(liquiddata, patterns, regex_patterns, inputtype="liquid"):
+ if not inputtype or inputtype == "liquid":
+ if "{{" not in liquiddata or "}}" not in liquiddata:
+ return liquiddata
+ elif inputtype == "json":
+ liquiddata = liquiddata.strip()
+
+ # Validating if it looks like json or not
+ if liquiddata[0] == "{" and liquiddata[len(liquiddata)-1] == "}":
+ pass
+ else:
+ if liquiddata[0] == "[" and liquiddata[len(liquiddata)-1] == "]":
+ pass
+ else:
+ return liquiddata
+
+ # If it's already json, don't touch it
+ try:
+ json.loads(liquiddata)
+ return liquiddata
+ except Exception as e:
+ pass
+ else:
+ print("No replace handler for %s" % inputtype)
+ return liquiddata
+
+ skipkeys = [" "]
+ newoutput = liquiddata[:]
+ for pattern in patterns:
+ keylocations = []
+ parsedvalue = ""
+ record = False
+ index = -1
+ for key in liquiddata:
+
+ # Return instant if possible
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ pass
+
+ index += 1
+ if not key:
+ if record:
+ keylocations.append(index)
+ parsedvalue += key
+
+ continue
+
+ if key in skipkeys:
+ if record:
+ keylocations.append(index)
+ parsedvalue += key
+
+ continue
+
+ if key == pattern[0] and not record:
+ record = True
+
+ if key not in pattern:
+ keylocations = []
+ parsedvalue = ""
+ record = False
+
+ if record:
+ keylocations.append(index)
+ parsedvalue += key
+
+ if len(parsedvalue) == 0:
+ continue
+
+ evaluated_value = parsedvalue[:]
+ for skipkey in skipkeys:
+ evaluated_value = "".join(evaluated_value.split(skipkey))
+
+ if evaluated_value == pattern:
+ #print("Found matching: %s (%s)" % (parsedvalue, keylocations))
+ #print("Should replace with: %s" % patterns[pattern])
+
+ newoutput = newoutput.replace(parsedvalue, patterns[pattern], -1)
+
+ # Return instant if possible
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ pass
+
+
+ for pattern in regex_patterns:
+ newlines = []
+ for line in newoutput.split("\n"):
+ replaced_line = re.sub(pattern, regex_patterns[pattern], line)
+ newlines.append(replaced_line)
+
+ newoutput = "\n".join(newlines)
+
+ # Return instant if possible
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ pass
+
+ # Dont return json properly unless actually json
+ if inputtype == "json":
+ try:
+ json.loads(newoutput)
+ return newoutput
+ except:
+ # Returns original if json fixing didn't work
+ return liquiddata
+
+ return newoutput
+
+print("Start:\n%s" % input_data)
+
+try:
+ newinput = patternfix_string(input_data,
+ {
+ "{{|": '{{ "" |',
+ },
+ {
+ #r'\{\{\s*|': "{{ '' |",
+ r'\{\{\s*\$[^|}]+\s*\|': '{{ "" |',
+ }
+ ,
+ inputtype="liquid"
+ )
+except Exception as e:
+ print("[ERROR} Failed liquid parsing fix: %s" % e)
+ newinput = input_data
+
+try:
+ newinput = patternfix_string(newinput,
+ {
+ },
+ {
+ r'\"\s*\:\s*,': '\": "",',
+ r'\"\s*\:\s*\$[^,]+\w*\,': '\": "",',
+ }
+ ,
+ inputtype="json"
+ )
+
+ try:
+ json.loads(newinput)
+ print("It's json! Override.")
+ except Exception as e:
+ print("Bad json. DONT use the value at all: %s" % e)
+except Exception as e:
+ print("[ERROR} Failed json parsing fix: %s" % e)
+
+print("\nEnd:\n%s" % newinput)
diff --git a/backend/app_sdk/recurse_test.py b/backend/app_sdk/recurse_test.py
index 9dfbd2c5..1cf2bfea 100644
--- a/backend/app_sdk/recurse_test.py
+++ b/backend/app_sdk/recurse_test.py
@@ -58,7 +58,7 @@ def recurse_json(basejson, parsersplit):
# Means it's a single item -> continue
if seconditem == "":
- print("[INFO] In first - handling %s. Len: %d" % (firstitem, len(basejson)))
+ #print("[INFO] In first - handling %s. Len: %d" % (firstitem, len(basejson)))
if str(firstitem).lower() == "max" or str(firstitem).lower() == "last" or str(firstitem).lower() == "end":
firstitem = len(basejson)-1
elif str(firstitem).lower() == "min" or str(firstitem).lower() == "first":
@@ -66,14 +66,14 @@ def recurse_json(basejson, parsersplit):
else:
firstitem = int(firstitem)
- print(f"[DEBUG] Post lower checks with item {firstitem}")
+ #print(f"[DEBUG] Post lower checks with item {firstitem}")
tmpitem = basejson[int(firstitem)]
try:
newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:])
except IndexError:
newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:])
else:
- print("[INFO] In ELSE - handling %s and %s" % (firstitem, seconditem))
+ #print("[INFO] In ELSE - handling %s and %s" % (firstitem, seconditem))
if isinstance(firstitem, str):
if firstitem.lower() == "max" or firstitem.lower() == "last" or firstitem.lower() == "end":
firstitem = len(basejson)-1
@@ -94,7 +94,7 @@ def recurse_json(basejson, parsersplit):
else:
seconditem = int(seconditem)
- print(f"[DEBUG] Post lower checks 2: {firstitem} AND {seconditem}")
+ #print(f"[DEBUG] Post lower checks 2: {firstitem} AND {seconditem}")
newvalue = []
if int(seconditem) > len(basejson):
seconditem = len(basejson)
@@ -106,7 +106,7 @@ def recurse_json(basejson, parsersplit):
try:
ret, tmp_loop = recurse_json(basejson[i], parsersplit[outercnt+1:])
except IndexError:
- print("[DEBUG] INDEXERROR: ", parsersplit[outercnt])
+ #print("[DEBUG] INDEXERROR (1): ", parsersplit[outercnt])
#ret = innervalue
ret, tmp_loop = recurse_json(basejson[i], parsersplit[outercnt:])
@@ -115,20 +115,18 @@ def recurse_json(basejson, parsersplit):
return newvalue, is_loop
else:
- print("IN ELSE WITH VALUE: %s" % value)
if len(value) == 0:
return basejson, False
try:
- print("PRINT:", basejson)
if isinstance(basejson, list):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
+ #print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
return basejson, False
elif isinstance(basejson, bool):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (bool): %s" % value)
+ #print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (bool): %s" % value)
return basejson, False
elif isinstance(basejson, int):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (int): %s" % value)
+ #print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (int): %s" % value)
return basejson, False
elif isinstance(basejson[value], str):
try:
@@ -136,8 +134,16 @@ def recurse_json(basejson, parsersplit):
basejson = json.loads(basejson[value])
else:
# Should we sanitize here?
- print("[DEBUG] VALUE TO SANITIZE?: %s" % basejson[value])
- return str(basejson[value]), False
+ #print("[DEBUG] VALUE TO SANITIZE FOR KEY '%s'?: %s" % (value, basejson[value]))
+
+ # Check if we are on the last item?
+ if outercnt == len(parsersplit)-1:
+ #print("[DEBUG] LAST KEY")
+ return str(basejson[value]), False
+ else:
+ #print("[DEBUG] NOT LAST KEY")
+ pass
+
except json.decoder.JSONDecodeError as e:
return str(basejson[value]), False
else:
@@ -151,42 +157,60 @@ def recurse_json(basejson, parsersplit):
try:
if isinstance(basejson, list):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
+ #print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
return basejson, False
elif isinstance(basejson, bool):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (bool): %s" % value)
+ #print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (bool): %s" % value)
return basejson, False
elif isinstance(basejson, int):
- print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (int): %s" % value)
+ #print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (int): %s" % value)
return basejson, False
elif isinstance(basejson[value], str):
- print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value])
+ #print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value])
try:
- print("[DEBUG] BASEJSON: %s" % basejson)
+ #print("[DEBUG] BASEJSON: %s" % basejson)
if (basejson[value].endswith("}") and basejson[value].endswith("}")) or (basejson[value].startswith("[") and basejson[value].endswith("]")):
basejson = json.loads(basejson[value])
else:
- return str(basejson[value]), False
+
+ if outercnt == len(parsersplit)-1:
+ #print("LAST KEY (2)")
+ return str(basejson[value]), False
+ else:
+ #print("NOT LAST KEY (2)")
+ pass
+
except json.decoder.JSONDecodeError as e:
- print("[DEBUG] RETURNING BECAUSE '%s' IS A NORMAL STRING (1)" % basejson[value])
+ #print("[DEBUG] RETURNING BECAUSE '%s' IS A NORMAL STRING (1)" % basejson[value])
return str(basejson[value]), False
else:
basejson = basejson[value]
except KeyError as e:
- print("\n\n[WARNING] Running third dot notation fix %s: %s" % (value, e))
+ # Check if previous key was handled or not
+ previouskey = parsersplit[outercnt-1]
+ #print("[DEBUG] PREVIOUS KEY: ", previouskey)
+
+ tmpval = previouskey + "." + value
+ #print("\n\n[WARNING] Running third dot notation fix '%s' on data %s: %s" % (value, basejson, e))
+ if tmpval in basejson:
+ return basejson[tmpval], False
try:
-
currentsplitcnt = splitcnt
+
recursed_value = value
handled = False
+
+ #tmpbase = basejson
+ previouskey = value
while True:
+ #print("\n\n[DEBUG] CURRENTSPLITCNT: ", currentsplitcnt)
newvalue = parsersplit[currentsplitcnt+1]
if newvalue == "#" or newvalue == "":
break
recursed_value += "." + newvalue
- print("\n\nRECURSED: ", recursed_value)
+ #print("\n\nRECURSED: ", recursed_value)
found = False
for key, value in basejson.items():
@@ -194,13 +218,27 @@ def recurse_json(basejson, parsersplit):
found = True
if found == False:
- print("[INFO] DIDN'T FIND similar VALUE: ", recursed_value)
- break
+ #print("[INFO] DIDN'T FIND similar VALUE: ", recursed_value)
+
+ # Check if we are on the last key or not
+ return "", False
+ #if outercnt == len(parsersplit)-1:
+ # print("[DEBUG] LAST KEY (3)")
+ # break
+ #else:
+ # print("[DEBUG] NOT LAST KEY (3)")
+ # return "", False
if recursed_value in basejson:
- print("[INFO] FOUND RECURSED VALUE: ", recursed_value)
+ #print("[INFO] FOUND RECURSED VALUE: ", recursed_value)
basejson = basejson[recursed_value]
- handled = True
+
+ # Whether to dig deeper or not
+ if isinstance(basejson, bool) or isinstance(basejson, int) or isinstance(basejson, str):
+ handled = False
+ else:
+ handled = True
+
break
currentsplitcnt += 1
@@ -210,8 +248,8 @@ def recurse_json(basejson, parsersplit):
break
except IndexError as e:
- print("[DEBUG] INDEXERROR: ", parsersplit[outercnt])
- break
+ print("[DEBUG] INDEXERROR (2):", parsersplit[outercnt])
+ return "", False
outercnt += 1
@@ -220,10 +258,7 @@ def recurse_json(basejson, parsersplit):
return "", False
except Exception as e:
print("[WARNING] Exception: %s" % e)
- return basejson, False
-
- #return basejson
- #return "KeyError: Couldn't find key: %s" % e
+ return "", False
return basejson, False
@@ -231,21 +266,61 @@ print("[INFO] Starting")
#input_data = "test"
#input_data = "test2.data"
-#input_data = "test2.test3.data"
-input_data = "test2.test5.data.hello"
-parsersplit = input_data.split(".")
+
+
+# Matchwith
basejson = {
"test": "hello",
"test2": {
- "data": "hello2",
+ "test3": "hello2",
"test3.data": "hello3",
"test4.data.testing": {
"value": "hello4"
},
- "test5.data.hello": "wut"
+ "test5.data.hello": "wut",
},
+ "test3": ["hello", "hello2", "hello3"],
+ "test4": [{
+ "id": "1",
+ }]
}
-ret, is_loop = recurse_json(basejson, parsersplit)
-print("\n\nOUTPUT RET (%s): %s" % (input_data, ret))
+# Inputexamples (ALL should be True)
+inputs = {
+ #"": "",
+ "badkey": "",
+ "test": "hello",
+ "test2.badkey": "",
+ "test2.test3": "hello2",
+ "test2.test3.data": "hello3",
+ "test2.test4.data.testing": "{'value': 'hello4'}", # FIXME: Doesn't work due to break vs return "", False in last exception
+ "test2.test4.data.testing.value": "hello4", # FIXME: Doesn't work due to break vs return "", False in last exception. Not fixed as we didn't find one of these yet.
+ "test2.test5.data.hello": "wut",
+ "test2.test5.data.badkey": "",
+ "test3.#1": "hello2",
+ "test4.#0.id": "1",
+ "test4.#1.id": "",
+}
+
+outputs = []
+for key, value in inputs.items():
+ parsersplit = key.split(".")
+ ret, is_loop = recurse_json(basejson, parsersplit)
+ print("\n\nOUTPUT RET (%s): %s" % (key, ret))
+
+ outputs.append("[%s]: %s = '%s' vs '%s'" % (str(ret) == str(value), key, ret, value))
+
+print("\n\n%s" % "\n".join(outputs))
+
+#input_data = ""
+#input_data = "badkey"
+#input_data = "test"
+#input_data = "test2.data"
+#input_data = "test2.test3.data"
+#input_data = "test2.test4.data.testing.value.as"
+#input_data = "test2.test5.data.hello"
+
+
+
+
diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go
index a4565523..03312201 100755
--- a/backend/go-app/docker.go
+++ b/backend/go-app/docker.go
@@ -20,6 +20,7 @@ import (
//"github.com/docker/docker"
"github.com/docker/docker/api/types"
//"github.com/docker/docker/api/types/container"
+ "github.com/docker/docker/api/types/image"
"github.com/docker/docker/client"
newdockerclient "github.com/fsouza/go-dockerclient"
"github.com/go-git/go-billy/v5"
@@ -565,7 +566,7 @@ func imageCheckBuilder(images []string) error {
return err
}
- filteredImages := []types.ImageSummary{}
+ filteredImages := []image.Summary{}
for _, image := range allImages {
found := false
for _, repoTag := range image.RepoTags {
@@ -636,10 +637,10 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) {
All: true,
})
- img := types.ImageSummary{}
+ img := image.Summary{}
tagFound := ""
- img2 := types.ImageSummary{}
+ img2 := image.Summary{}
tagFound2 := ""
alternativeNameSplit := strings.Split(version.Name, "/")
@@ -798,7 +799,7 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) {
// Downloads and activates an app from shuffler.io if possible
func handleRemoteDownloadApp(resp http.ResponseWriter, ctx context.Context, user shuffle.User, appId string) {
url := fmt.Sprintf("https://shuffler.io/api/v1/apps/%s/config", appId)
- log.Printf("Downloading API from %s", url)
+ log.Printf("[DEBUG] Downloading API from URL %s", url)
req, err := http.NewRequest(
"GET",
url,
@@ -812,7 +813,7 @@ func handleRemoteDownloadApp(resp http.ResponseWriter, ctx context.Context, user
return
}
- httpClient := &http.Client{}
+ httpClient := shuffle.GetExternalClient(url)
newresp, err := httpClient.Do(req)
if err != nil {
log.Printf("[ERROR] Failed running auto-download request for %s: %s", appId, err)
@@ -822,6 +823,7 @@ func handleRemoteDownloadApp(resp http.ResponseWriter, ctx context.Context, user
}
defer newresp.Body.Close()
+
respBody, err := ioutil.ReadAll(newresp.Body)
if err != nil {
log.Printf("[ERROR] Failed setting respbody for workflow download: %s", err)
diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod
index fbb6f872..6e4b2ef2 100644
--- a/backend/go-app/go.mod
+++ b/backend/go-app/go.mod
@@ -1,122 +1,149 @@
-module shuffle-shared
+module shuffle
+
+go 1.22.0
// replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared
-go 1.19
+toolchain go1.22.2
require (
- cloud.google.com/go/datastore v1.11.0
- cloud.google.com/go/storage v1.30.1
+ cloud.google.com/go/datastore v1.15.0
+ cloud.google.com/go/storage v1.40.0
github.com/basgys/goxml2json v1.1.0
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82
- github.com/docker/docker v24.0.2+incompatible
+ github.com/docker/docker v26.1.0+incompatible
github.com/frikky/kin-openapi v0.42.0
- github.com/fsouza/go-dockerclient v1.9.7
+ github.com/fsouza/go-dockerclient v1.11.0
github.com/ghodss/yaml v1.0.0
github.com/go-git/go-billy/v5 v5.5.0
- github.com/go-git/go-git/v5 v5.11.0
- github.com/gorilla/mux v1.8.0
+ github.com/go-git/go-git/v5 v5.12.0
+ github.com/gorilla/mux v1.8.1
github.com/h2non/filetype v1.1.3
github.com/satori/go.uuid v1.2.0
- github.com/shuffle/shuffle-shared v0.5.72
- golang.org/x/crypto v0.16.0
- google.golang.org/api v0.125.0
- google.golang.org/grpc v1.55.0
+ github.com/shuffle/shuffle-shared v0.6.27
+ golang.org/x/crypto v0.22.0
+ google.golang.org/api v0.176.1
+ google.golang.org/grpc v1.63.2
+
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v3 v3.0.1
- k8s.io/api v0.22.5
- k8s.io/apimachinery v0.22.5
- k8s.io/client-go v0.22.5
+ k8s.io/api v0.30.0
+ k8s.io/apimachinery v0.30.0
+ k8s.io/client-go v0.30.0
)
require (
- cloud.google.com/go v0.110.2 // indirect
- cloud.google.com/go/compute v1.19.3 // indirect
- cloud.google.com/go/compute/metadata v0.2.3 // indirect
- cloud.google.com/go/iam v1.0.1 // indirect
+ cloud.google.com/go v0.112.1 // indirect
+ cloud.google.com/go/auth v0.3.0 // indirect
+ cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
+ cloud.google.com/go/compute/metadata v0.3.0 // indirect
+ cloud.google.com/go/iam v1.1.7 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
- github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
+
+ github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/adrg/strutil v0.2.3 // indirect
github.com/algolia/algoliasearch-client-go/v3 v3.18.1 // indirect
- github.com/bitly/go-simplejson v0.5.0 // indirect
+ github.com/bitly/go-simplejson v0.5.1 // indirect
+
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 // indirect
- github.com/cloudflare/circl v1.3.3 // indirect
- github.com/containerd/containerd v1.6.18 // indirect
+ github.com/cloudflare/circl v1.3.7 // indirect
+ github.com/containerd/containerd v1.6.26 // indirect
+ github.com/containerd/log v0.1.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/docker/distribution v2.8.2+incompatible // indirect
+ github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
+ github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
- github.com/frikky/schemaless v0.0.5 // indirect
+
+ github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/frikky/schemaless v0.0.11 // indirect
+
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
- github.com/go-logr/logr v1.2.4 // indirect
- github.com/go-openapi/jsonpointer v0.19.5 // indirect
- github.com/go-openapi/swag v0.19.5 // indirect
+ github.com/go-logr/logr v1.4.1 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/go-openapi/jsonpointer v0.19.6 // indirect
+ github.com/go-openapi/jsonreference v0.20.2 // indirect
+ github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/golang/protobuf v1.5.3 // indirect
- github.com/google/go-cmp v0.6.0 // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
+ github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-github/v28 v28.1.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/s2a-go v0.1.4 // indirect
- github.com/google/uuid v1.3.0 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
- github.com/googleapis/gax-go/v2 v2.10.0 // indirect
- github.com/googleapis/gnostic v0.5.5 // indirect
+
+ github.com/google/s2a-go v0.1.7 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
+ github.com/googleapis/gax-go/v2 v2.12.3 // indirect
+
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
- github.com/klauspost/compress v1.11.13 // indirect
- github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e // indirect
- github.com/moby/patternmatcher v0.5.0 // indirect
+ github.com/klauspost/compress v1.15.9 // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/moby/docker-image-spec v1.3.1 // indirect
+ github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
+ github.com/moby/sys/user v0.1.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
- github.com/opencontainers/runc v1.1.5 // indirect
+ github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/opensearch-project/opensearch-go v1.1.0 // indirect
github.com/opensearch-project/opensearch-go/v2 v2.3.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sashabaranov/go-openai v1.19.2 // indirect
- github.com/sergi/go-diff v1.1.0 // indirect
- github.com/sirupsen/logrus v1.9.0 // indirect
- github.com/skeema/knownhosts v1.2.1 // indirect
+
+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/skeema/knownhosts v1.2.2 // indirect
+
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/src-d/gcfg v1.4.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.opencensus.io v0.24.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
+ go.opentelemetry.io/otel v1.24.0 // indirect
+ go.opentelemetry.io/otel/metric v1.24.0 // indirect
+ go.opentelemetry.io/otel/trace v1.24.0 // indirect
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
- golang.org/x/mod v0.12.0 // indirect
- golang.org/x/net v0.19.0 // indirect
- golang.org/x/oauth2 v0.8.0 // indirect
- golang.org/x/sys v0.15.0 // indirect
- golang.org/x/term v0.15.0 // indirect
+ golang.org/x/mod v0.15.0 // indirect
+ golang.org/x/net v0.24.0 // indirect
+ golang.org/x/oauth2 v0.19.0 // indirect
+ golang.org/x/sync v0.7.0 // indirect
+ golang.org/x/sys v0.19.0 // indirect
+ golang.org/x/term v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
- golang.org/x/time v0.3.0 // indirect
- golang.org/x/tools v0.13.0 // indirect
- golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
+
+ golang.org/x/time v0.5.0 // indirect
+ golang.org/x/tools v0.18.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
- google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
- google.golang.org/protobuf v1.30.0 // indirect
+ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
+ google.golang.org/protobuf v1.33.0 // indirect
+
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
- k8s.io/klog/v2 v2.30.0 // indirect
- k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
- sigs.k8s.io/yaml v1.2.0 // indirect
-
+ k8s.io/klog/v2 v2.120.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
+ k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
+ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
+ sigs.k8s.io/yaml v1.3.0 // indirect
)
diff --git a/backend/go-app/go.sum b/backend/go-app/go.sum
index f119a704..358b0d50 100644
--- a/backend/go-app/go.sum
+++ b/backend/go-app/go.sum
@@ -16,25 +16,27 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
-cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
-cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
+cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
+cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
+cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs=
+cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w=
+cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
+cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds=
-cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI=
-cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
-cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
+cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
+cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/datastore v1.4.0/go.mod h1:d18825/a9bICdAIJy2EkHs9joU4RlIZ1t6l8WDdbdY0=
-cloud.google.com/go/datastore v1.11.0 h1:iF6I/HaLs3Ado8uRKMvZRvF/ZLkWaWE9i8AiHzbC774=
-cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c=
-cloud.google.com/go/iam v1.0.1 h1:lyeCAU6jpnVNrE9zGQkTl3WgNgK/X+uWwaw0kynZJMU=
-cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8=
+cloud.google.com/go/datastore v1.15.0 h1:0P9WcsQeTWjuD1H14JIY7XQscIPQ4Laje8ti96IC5vg=
+cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8=
+cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM=
+cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -45,40 +47,27 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho=
-cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
-cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
+cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw=
+cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 h1:V8krnnfGj4pV65YLUm3C0/8bl7V5Nry2Pwvy3ru/wLc=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
-github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
-github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
-github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
-github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
-github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
-github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
-github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
-github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
-github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
-github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY=
-github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
-github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek=
-github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
-github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
+github.com/Microsoft/hcsshim v0.9.10 h1:TxXGNmcbQxBKVWvjvTocNb6jrPyeHlk5EiDhhgHgggs=
+github.com/Microsoft/hcsshim v0.9.10/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
-github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
-github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
+github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
+github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/adrg/strutil v0.2.3 h1:WZVn3ItPBovFmP4wMHHVXUr8luRaHrbyIuLlHt32GZQ=
github.com/adrg/strutil v0.2.3/go.mod h1:+SNxbiH6t+O+5SZqIj5n/9i5yUjR+S3XXVrjEcN2mxg=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
@@ -88,10 +77,8 @@ github.com/algolia/algoliasearch-client-go/v3 v3.18.1/go.mod h1:i7tLoP7TYDmHX3Q7
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
-github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.42.27/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc=
github.com/aws/aws-sdk-go v1.44.263/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
@@ -108,64 +95,53 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jely
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
-github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
-github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
-github.com/bradfitz/gomemcache v0.0.0-20221031212613-62deef7fc822 h1:hjXJeBcAMS1WGENGqDpzvmgS43oECTx8UXq31UBu0Jw=
-github.com/bradfitz/gomemcache v0.0.0-20221031212613-62deef7fc822/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
+github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow=
+github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q=
+github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
+github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 h1:/P9/RL0xgWE+ehnCUUN5h3RpG3dmoMCOONO1CCvq23Y=
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013/go.mod h1:pccXHIvs3TV/TUqSNyEvF99sxjX2r4FFRIyw6TZY9+w=
-github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82 h1:9bAydALqAjBfPHd/eAiJBHnMZUYov8m2PkXVr+YGQeI=
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82/go.mod h1:tyA14J0sA3Hph4dt+AfCjPrYR13+vVodshQSM7km9qw=
+github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
+github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
-github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
-github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns=
-github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw=
-github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs=
+github.com/containerd/containerd v1.6.26/go.mod h1:I4TRdsdoo5MlKob5khDJS2EPT1l1oMNaE2MBm6FrwxM=
+github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
+github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
-github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg=
-github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/docker/docker v26.1.0+incompatible h1:W1G9MPNbskA6VZWL7b3ZljTh0pXI68FpINx0GKaOdaM=
+github.com/docker/docker v26.1.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
-github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
-github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
+github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
-github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
+github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
@@ -173,59 +149,58 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
-github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
-github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
-github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frikky/kin-openapi v0.41.0/go.mod h1:ev9OZAw7Bv5p0w93j91++6a1ElPzGcCofst+kmrWsj4=
github.com/frikky/kin-openapi v0.42.0 h1:d5Z6vnuQ6RnCCPIxZaDL+TH2ODLxT8abytOt+Zh+Kd0=
github.com/frikky/kin-openapi v0.42.0/go.mod h1:ev9OZAw7Bv5p0w93j91++6a1ElPzGcCofst+kmrWsj4=
+github.com/frikky/schemaless v0.0.9 h1:RzNLPkJq5c4nlm5iLiTndFcbeQxdMGJIj266wSGt2+8=
+github.com/frikky/schemaless v0.0.9/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ=
+github.com/frikky/schemaless v0.0.11 h1:c4r6CJX30XI+SoJdT9RlUd9qYSQlx6hvwGRtsypu+uM=
+github.com/frikky/schemaless v0.0.11/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsouza/go-dockerclient v1.9.7 h1:FlIrT71E62zwKgRvCvWGdxRD+a/pIy+miY/n3MXgfuw=
-github.com/fsouza/go-dockerclient v1.9.7/go.mod h1:vx9C32kE2D15yDSOMCDaAEIARZpDQDFBHeqL3MgQy/U=
+github.com/fsouza/go-dockerclient v1.11.0 h1:4ZAk6W7rPAtPXm7198EFqA5S68rwnNQORxlOA5OurCA=
+github.com/fsouza/go-dockerclient v1.11.0/go.mod h1:0I3TQCRseuPTzqlY4Y3ajfsg2VAdMQoazrkxJTiJg8s=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
-github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
+github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
+github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
-github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
-github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
-github.com/go-git/go-git/v5 v5.7.0 h1:t9AudWVLmqzlo+4bqdf7GY+46SUuRsx59SboFxkq2aE=
-github.com/go-git/go-git/v5 v5.7.0/go.mod h1:coJHKEOk5kUClpsNlXrUvPrDxY3w3gjHvhcZd8Fodw8=
-github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
+github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
+github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
-github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
+github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
+github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
-github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
+github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
+github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
+github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
+github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
-github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -257,11 +232,13 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
+github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
+github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -274,7 +251,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -283,7 +259,6 @@ github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv3
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
@@ -291,6 +266,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
+github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -302,27 +278,23 @@ github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
+github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
-github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
-github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
+github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
-github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
+github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.10.0 h1:ebSgKfMxynOdxw8QQuFOKMgomqeLGPqNLQox2bo42zg=
-github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw=
-github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
-github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
-github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA=
+github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
@@ -331,16 +303,13 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
-github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
@@ -350,54 +319,48 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4=
-github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
+github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/libgit2/git2go/v34 v34.0.0/go.mod h1:blVco2jDAw6YTXkErMMqzHLcAjKkwF0aWIRHBqiJkZ0=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
-github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
-github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
-github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
-github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
+github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
+github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
+github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
+github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
+github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
+github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
-github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
-github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
@@ -413,7 +376,8 @@ github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxe
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
-github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
+github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
@@ -431,14 +395,12 @@ github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+q
github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
+github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE=
+github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
-github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
-github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
-github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
+github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
+github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/opensearch-project/opensearch-go v1.1.0 h1:eG5sh3843bbU1itPRjA9QXbxcg8LaZ+DjEzQH9aLN3M=
github.com/opensearch-project/opensearch-go v1.1.0/go.mod h1:+6/XHCuTH+fwsMJikZEWsucZ4eZMma3zNSeLrTtVGbo=
github.com/opensearch-project/opensearch-go/v2 v2.3.0 h1:nQIEMr+A92CkhHrZgUhcfsrZjibvB3APXf2a1VwCmMQ=
@@ -446,7 +408,6 @@ github.com/opensearch-project/opensearch-go/v2 v2.3.0/go.mod h1:8LDr9FCgUTVoT+5E
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
-github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@@ -456,71 +417,44 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
+github.com/sashabaranov/go-openai v1.19.2 h1:+dkuCADSnwXV02YVJkdphY8XD9AyHLUWwk6V7LB6EL8=
+github.com/sashabaranov/go-openai v1.19.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
-github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shuffle/shuffle-shared v0.4.66 h1:Aw4qOp0VsVJrRzW1sJhEy4OY4fRGlFErUD5+93RXL6g=
-github.com/shuffle/shuffle-shared v0.4.66/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.4.80 h1:03OL+O8prwL9zq6Gnb9SRORPWi5+ThO0jPoxk+xctOo=
-github.com/shuffle/shuffle-shared v0.4.80/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.4.95 h1:xr92/03/uQeJiDme9S8/vgF1KWyQgJ1KQXVE7nQMKis=
-github.com/shuffle/shuffle-shared v0.4.95/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.4.96 h1:iaIB/HP9eKpw9DMMJZhSLDbKdHJt075kFYLHg9AaiiM=
-github.com/shuffle/shuffle-shared v0.4.96/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.4.97 h1:1c8LdNteMykKNEV97vwP63oSP2tV/Uso3O4TC+oxdFQ=
-github.com/shuffle/shuffle-shared v0.4.97/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.4.98 h1:pgsLdWUpxZ/q+eHpAjOCH9icOsmuO5u2olmirOldy5A=
-github.com/shuffle/shuffle-shared v0.4.98/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.11 h1:Eqbs9o8E49QAL5/6aV6BfFtWSjLIvgET7AL3fa4OQTg=
-github.com/shuffle/shuffle-shared v0.5.11/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.14 h1:d14u1e4k+qKgnf4Insq4x2S+0MMKlDqdyTTyVP3puRA=
-github.com/shuffle/shuffle-shared v0.5.14/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.29 h1:n4vThl7v3mFVXbrIW71XREFdmZZo7mOBAWxnsdiNjDk=
-github.com/shuffle/shuffle-shared v0.5.29/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.30 h1:ORWjQU3UJhdZY5mRsAoR2hvftNcJmiEekNKjbaMo7K8=
-github.com/shuffle/shuffle-shared v0.5.30/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.31 h1:OV4IIfKWWFW66WjGvyXOmmsSz3p8pW9L1ge1mDo8ftM=
-github.com/shuffle/shuffle-shared v0.5.31/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.44 h1:6WiFPIsij+IWvXY7vzVX7cUicb+PYOzhTbWF/gDmYeU=
-github.com/shuffle/shuffle-shared v0.5.44/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
-github.com/shuffle/shuffle-shared v0.5.60 h1:R0BWYp/DlgyNPU0xVNSPhsWBnJ+LeVD3iLoDRZmtKMo=
-github.com/shuffle/shuffle-shared v0.5.60/go.mod h1:oIZkx93Z7EvtiTXty7xO+ax63Fjz8MQvjXMxDN0Qws0=
-github.com/shuffle/shuffle-shared v0.5.61 h1:Fkd7pvk8ypwaio1VvMOmJ6PQF9xCfNYx8RWjPnXjn5E=
-github.com/shuffle/shuffle-shared v0.5.61/go.mod h1:oIZkx93Z7EvtiTXty7xO+ax63Fjz8MQvjXMxDN0Qws0=
-github.com/shuffle/shuffle-shared v0.5.62 h1:L1la7++aqPLPsh1z3cuGIzH+NTuvBlmEU/T2mQvfEk8=
-github.com/shuffle/shuffle-shared v0.5.62/go.mod h1:oIZkx93Z7EvtiTXty7xO+ax63Fjz8MQvjXMxDN0Qws0=
-github.com/shuffle/shuffle-shared v0.5.65 h1:x4ZM+e0LK21rRtG0xbtnUb+6qU08+zNBQ6azUyhn8ck=
-github.com/shuffle/shuffle-shared v0.5.65/go.mod h1:oIZkx93Z7EvtiTXty7xO+ax63Fjz8MQvjXMxDN0Qws0=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
+github.com/shuffle/shuffle-shared v0.6.16 h1:dQBDRmb2Wgl3pEuewqjDvN6v6nUKr+1EvGSEja9zG6s=
+github.com/shuffle/shuffle-shared v0.6.16/go.mod h1:HhQTn7xZZ69ZTc4EptO9OeNmgbKDyGlWAhFkUFUAHSA=
+github.com/shuffle/shuffle-shared v0.6.18 h1:mKc3vGuCz9ubdqMwaLocSbEUZyso620CY73RBqcF6LI=
+github.com/shuffle/shuffle-shared v0.6.18/go.mod h1:00QOcSPlUWMXzJj1D7pjcV9h6nVRWfSWqTM10+fhTd0=
+github.com/shuffle/shuffle-shared v0.6.24 h1:gSUsI7o7DG0Z/AYtDQuSvhivWVV4MQPa5JU08YKAy2U=
+github.com/shuffle/shuffle-shared v0.6.24/go.mod h1:rWkh1eWdIx7OqQzJ1+JzF3Hck1X/Ty1WkUtjLrp+CU4=
+github.com/shuffle/shuffle-shared v0.6.26 h1:UZ4o3s+GPULLv/gy31SdhUw1ttvF+f1FfP18bxD7+Bw=
+github.com/shuffle/shuffle-shared v0.6.26/go.mod h1:rWkh1eWdIx7OqQzJ1+JzF3Hck1X/Ty1WkUtjLrp+CU4=
+github.com/shuffle/shuffle-shared v0.6.27 h1:q4qZD6bGZFIvZ5Y10unGr3N3rZ7OryWyvvaGgANZJZU=
+github.com/shuffle/shuffle-shared v0.6.27/go.mod h1:rWkh1eWdIx7OqQzJ1+JzF3Hck1X/Ty1WkUtjLrp+CU4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
-github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
-github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
+github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
-github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -534,13 +468,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
-github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
@@ -558,7 +489,26 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
+go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
+go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
+go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0 h1:R/OBkMoGgfy2fLhs2QhkCI1w4HLEQX92GCcJB6SSdNk=
+go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0 h1:giGm8w67Ja7amYNfYMdme7xSp2pIxThWopw8+QP51Yk=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0 h1:Ydage/P0fRrSPpZeCVxzjqGcI6iVmG2xb43+IR8cjqM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE=
+go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
+go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
+go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
+go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
+go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
+go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
+go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
+go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
go4.org v0.0.0-20201209231011-d4a079459e60 h1:iqAGo78tVOJXELHQFRjR6TMwItrvXH4hrGJ32I/NFF8=
go4.org v0.0.0-20201209231011-d4a079459e60/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@@ -569,11 +519,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
-golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
@@ -581,10 +527,9 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
-golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
+golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -622,12 +567,12 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -641,7 +586,6 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -666,7 +610,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@@ -682,10 +625,9 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
+golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
+golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -695,8 +637,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210113160501-8b1d76fa0423/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
-golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
+golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
+golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -709,9 +651,10 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -721,14 +664,12 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -743,7 +684,6 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -751,17 +691,12 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -780,13 +715,11 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
+golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -798,10 +731,9 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
-golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
-golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
+golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -818,16 +750,14 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
-golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -885,19 +815,19 @@ golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
-golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
-golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
+golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
-golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
+golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -918,16 +848,17 @@ google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQW
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.125.0 h1:7xGvEY4fyWbhWMHf3R2/4w7L4fXyfpRGE9g6lp8+DCk=
-google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
+google.golang.org/api v0.176.1 h1:DJSXnV6An+NhJ1J+GWtoF2nHEuqB1VNoTfnIbjNvwD4=
+google.golang.org/api v0.176.1/go.mod h1:j2MaSDYcvYV1lkZ1+SMW4IeF90SrEyFA+tluDYWRrFg=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -951,7 +882,6 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
@@ -962,17 +892,16 @@ google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210113195801-ae06605f4595/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao=
-google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
-google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
-google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
+google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
+google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
+google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c h1:kaI7oewGK5YnVwj+Y+EJBO/YN1ht8iTL9XkFHtVZLsc=
+google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c/go.mod h1:VQW3tUculP/D4B+xVCo+VgSq8As6wA9ZjHl//pmk+6s=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -987,14 +916,11 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.34.1/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
-google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
-google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
+google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
+google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1007,14 +933,12 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
@@ -1030,21 +954,18 @@ gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQb
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
-gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
+gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
+gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1052,27 +973,25 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.22.5 h1:xk7C+rMjF/EGELiD560jdmwzrB788mfcHiNbMQLIVI8=
-k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs=
-k8s.io/apimachinery v0.22.5 h1:cIPwldOYm1Slq9VLBRPtEYpyhjIm1C6aAMAoENuvN9s=
-k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U=
-k8s.io/client-go v0.22.5 h1:I8Zn/UqIdi2r02aZmhaJ1hqMxcpfJ3t5VqvHtctHYFo=
-k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y=
-k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
-k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
-k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
-k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
-k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs=
-k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA=
+k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE=
+k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA=
+k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
+k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ=
+k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY=
+k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
+k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
+k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
-sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
-sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
+sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
+sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
+sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index ddcb66df..62870a45 100755
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -580,7 +580,7 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
Name: orgSetupName,
Id: orgId,
Org: orgSetupName,
- Users: []shuffle.User{},
+ Users: []shuffle.User{user},
Roles: []string{"admin", "user"},
CloudSync: false,
}
@@ -614,6 +614,8 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
Id: newOrg.Id,
Name: newOrg.Name,
}
+
+ user.ActiveOrg = currentOrg
}
}
}
@@ -876,6 +878,11 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
}
org, err := shuffle.GetOrg(ctx, userInfo.ActiveOrg.Id)
+ if err != nil {
+ log.Printf("[DEBUG] Failed to get org during getinfo: %s", err)
+ }
+
+
//if err == nil {
if len(org.Id) > 0 {
userInfo.ActiveOrg = shuffle.OrgMini{
@@ -964,6 +971,8 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
tutorialsFinished = append(tutorialsFinished, tutorial)
}
+ licensed := shuffle.IsLicensed(ctx, *org)
+
returnValue := shuffle.HandleInfo{
Success: true,
Username: userInfo.Username,
@@ -983,6 +992,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
Tutorials: tutorialsFinished,
Priorities: orgPriorities,
+ Licensed: licensed,
}
returnData, err := json.Marshal(returnValue)
@@ -1965,6 +1975,144 @@ func handleWebhookCallback(resp http.ResponseWriter, request *http.Request) {
}
+func handlePipelineCallback(resp http.ResponseWriter, request *http.Request) {
+
+ if request.Method != "POST" {
+ request.Method = "POST"
+ }
+
+ if request.Body == nil {
+ stringReader := strings.NewReader("")
+ request.Body = ioutil.NopCloser(stringReader)
+ }
+
+ path := strings.Split(request.URL.String(), "/")
+ if len(path) < 4 {
+ resp.WriteHeader(403)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ ctx := context.Background()
+ location := strings.Split(request.URL.String(), "/")
+
+ var pipelineId string
+
+ if location[1] == "api" {
+ if len(location) <= 4 {
+ log.Printf("[INFO] Couldn't handle location. Too short in pipeline: %d", len(location))
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ pipelineId = location[4]
+ }
+
+ userAgent := request.Header.Get("User-Agent")
+ if strings.Contains(strings.ToLower(userAgent), "microsoftpreview") || strings.Contains(strings.ToLower(userAgent), "googlebot") {
+ log.Printf("[AUDIT] Blocking googlebot and microsoftbot for pielines. UA: '%s'", userAgent)
+ resp.WriteHeader(400)
+ resp.Write([]byte(`{"success": false, "reason": "Google/Microsoft preview bots not allowed. Please change the useragent."}`))
+ return
+ }
+
+ if len(pipelineId) != 45 {
+ log.Printf("[INFO] Couldn't handle pipeline. Too short in pipeline: %d", len(pipelineId))
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false, "reason": "pipeline ID not valid"}`))
+ return
+ }
+
+ pipelineId = pipelineId[9:]
+
+ pipeline, err := shuffle.GetPipeline(ctx, pipelineId)
+ if err != nil {
+ log.Printf("[WARNING] Failed getting pipeline %s (callback): %s", pipelineId, err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ if pipeline.Status != "running" {
+ log.Printf("[WARNING] Not running %s because pipeline status is %s", pipeline.TriggerId, pipeline.Status)
+ resp.WriteHeader(401)
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "The pipeline isn't running"}`)))
+ return
+ }
+
+ if pipeline.WorkflowId == "" {
+ log.Printf("[DEBUG] Not running because pipeline isn't connected to any workflows")
+ resp.WriteHeader(401)
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No workflows are defined"}`)))
+ return
+ }
+
+ body, err := ioutil.ReadAll(request.Body)
+ if err != nil {
+ log.Printf("[DEBUG] Body data error: %s", err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ parsedBody := shuffle.GetExecutionbody(body)
+ newBody := shuffle.ExecutionStruct{
+ Start: pipeline.StartNode,
+ ExecutionSource: "pipeline",
+ ExecutionArgument: parsedBody,
+ }
+
+ workflow, err := shuffle.GetWorkflow(ctx, pipeline.WorkflowId)
+ if err == nil {
+ for _, branch := range workflow.Branches {
+ if branch.SourceID == pipeline.TriggerId {
+ log.Printf("[DEBUG] Found ID %s for pipeline", pipeline.TriggerId)
+ if branch.DestinationID != pipeline.StartNode {
+ newBody.Start = branch.DestinationID
+ break
+ }
+ }
+ }
+ }
+
+ b, err := json.Marshal(newBody)
+ if err != nil {
+ log.Printf("[ERROR] Failed newBody marshaling for pipeline: %s", err)
+ resp.WriteHeader(500)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ log.Printf("[INFO] Running pipeline for workflow %s with startnode %s", pipeline.WorkflowId, pipeline.StartNode)
+
+ newWorkflow := shuffle.Workflow{
+ ID: "",
+ }
+
+ if len(pipeline.StartNode) == 0 {
+ log.Printf("[WARNING] No start node for pipeline %s - running with workflow default.", pipeline.TriggerId)
+
+ }
+
+ newRequest := &http.Request{
+ URL: &url.URL{},
+ Method: "POST",
+ Body: ioutil.NopCloser(bytes.NewReader(b)),
+ }
+
+ workflowExecution, executionResp, err := handleExecution(pipeline.WorkflowId, newWorkflow, newRequest, pipeline.OrgId)
+
+ if err == nil {
+ resp.WriteHeader(200)
+ resp.Write([]byte(fmt.Sprintf(`{"success": true, "execution_id": "%s"}`, workflowExecution.ExecutionId)))
+ return
+ }
+
+ resp.WriteHeader(500)
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, executionResp)))
+}
+
func executeCloudAction(action shuffle.CloudSyncJob, apikey string) error {
data, err := json.Marshal(action)
if err != nil {
@@ -1972,13 +2120,8 @@ func executeCloudAction(action shuffle.CloudSyncJob, apikey string) error {
return err
}
- //transport := http.DefaultTransport.(*http.Transport).Clone()
- //client := &http.Client{
- // Transport: transport,
- //}
- client := &http.Client{}
-
syncUrl := fmt.Sprintf("%s/api/v1/cloud/sync/handle_action", syncUrl)
+ client := shuffle.GetExternalClient(syncUrl)
req, err := http.NewRequest(
"POST",
syncUrl,
@@ -3044,6 +3187,26 @@ func buildSwaggerApp(resp http.ResponseWriter, body []byte, user shuffle.User, s
return
}
+ if len(user.ActiveOrg.Id) > 0 {
+ org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id)
+ if err != nil {
+ log.Printf("[ERROR] Failed getting org during image build (%s): %s", user.ActiveOrg.Id, err)
+ } else {
+ log.Printf("[INFO] Successfully uploaded app %s to org %s (2). Validating and distributing image to available environments in org.", api.ID, org.Id)
+
+ imagenames := []string{
+ fmt.Sprintf("%s_%s", api.Name, api.AppVersion),
+ fmt.Sprintf("%s_%s", api.Name, test.Id),
+ }
+
+ err = shuffle.DistributeAppToEnvironments(ctx, *org, imagenames)
+ if err != nil {
+ log.Printf("[ERROR] Failed distributing app to environments: %s", err)
+ }
+ }
+ }
+
+
log.Printf("[DEBUG] Successfully built app %s (%s)", api.Name, api.ID)
if len(user.Id) > 0 {
resp.WriteHeader(200)
@@ -3483,8 +3646,8 @@ func remoteOrgJobHandler(org shuffle.Org, interval int) error {
}
- client := &http.Client{}
syncUrl := fmt.Sprintf("%s/api/v1/cloud/sync", syncUrl)
+ client := shuffle.GetExternalClient(syncUrl)
req, err := http.NewRequest(
"POST",
syncUrl,
@@ -3560,8 +3723,8 @@ func runInitEs(ctx context.Context) {
setUsers := false
_ = setUsers
if err != nil {
- if fmt.Sprintf("%s", err) == "EOF" {
- time.Sleep(7 * time.Second)
+ if fmt.Sprintf("%s", err) == "EOF" || strings.Contains(fmt.Sprintf("%s", err), "bad status") {
+ time.Sleep(10 * time.Second)
runInitEs(ctx)
return
}
@@ -3645,7 +3808,7 @@ func runInitEs(ctx context.Context) {
if strings.Contains(os.Getenv("SHUFFLE_OPENSEARCH_URL"), "https") {
log.Printf("[INFO] Waiting during init to make sure the opensearch instance is up and running with security features properly")
- time.Sleep(15 * time.Second)
+ time.Sleep(30 * time.Second)
}
schedules, err := shuffle.GetAllSchedules(ctx, "ALL")
@@ -3867,6 +4030,9 @@ func runInitEs(ctx context.Context) {
log.Printf("[INFO] Running schedule for cleaning up or re-running unfinished workflows in %d environments.", len(environments))
for _, environment := range environments {
+ // Allowed without PROXY management as it's localhost
+ // client := shuffle.GetExternalClient(syncUrl)
+
httpClient := &http.Client{}
url := fmt.Sprintf("http://localhost:5001/api/v1/environments/%s/stop", environment)
req, err := http.NewRequest(
@@ -4077,7 +4243,7 @@ func handleVerifyCloudsync(orgId string) (shuffle.SyncFeatures, error) {
//r.HandleFunc("/api/v1/getorgs", handleGetOrgs).Methods("GET", "OPTIONS")
syncURL := fmt.Sprintf("%s/api/v1/cloud/sync/get_access", syncUrl)
- client := &http.Client{}
+ client := shuffle.GetExternalClient(syncURL)
req, err := http.NewRequest(
"GET",
syncURL,
@@ -4121,7 +4287,7 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error)
log.Printf("[INFO] Should run cloud sync disable for org %s with URL %s and sync key %s", org.Id, syncUrl, org.SyncConfig.Apikey)
- client := &http.Client{}
+ client := shuffle.GetExternalClient(syncUrl)
req, err := http.NewRequest(
"DELETE",
syncUrl,
@@ -4292,7 +4458,6 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
//log.Printf("Apidata: %s", tmpData.Apikey)
// FIXME: Path
- client := &http.Client{}
apiPath := "/api/v1/cloud/sync/setup"
if tmpData.Disable {
if !org.CloudSync {
@@ -4362,6 +4527,7 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
bytes.NewBuffer(b),
)
+ client := shuffle.GetExternalClient(syncPath)
newresp, err := client.Do(req)
if err != nil {
resp.WriteHeader(400)
@@ -4754,6 +4920,7 @@ func initHandlers() {
r.HandleFunc("/api/v1/users/checkusers", checkAdminLogin).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/users/getinfo", handleInfo).Methods("GET", "OPTIONS")
+ r.HandleFunc("/api/v1/users/apps", shuffle.HandleGetUserApps).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/users/generateapikey", shuffle.HandleApiGeneration).Methods("GET", "POST", "OPTIONS")
r.HandleFunc("/api/v1/users/logout", shuffle.HandleLogout).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/users/getsettings", shuffle.HandleSettings).Methods("GET", "OPTIONS")
@@ -4882,7 +5049,10 @@ func initHandlers() {
r.HandleFunc("/api/v1/triggers/outlook/{key}", shuffle.HandleGetSpecificTrigger).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/triggers/gmail/register", shuffle.HandleNewGmailRegister).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/triggers/gmail/getFolders", shuffle.HandleGetGmailFolders).Methods("GET", "OPTIONS")
-
+ r.HandleFunc("/api/v1/triggers/pipeline", shuffle.HandleNewPipelineRegister).Methods("POST", "OPTIONS")
+ //r.HandleFunc("/api/v1/triggers/pipeline/save", shuffle.HandleSavePipelineInfo).Methods("PUT", "OPTIONS")
+ r.HandleFunc("/api/v1/pipelines/{key}", handlePipelineCallback).Methods("POST", "GET", "PATCH", "PUT", "DELETE", "OPTIONS")
+ r.HandleFunc("/api/v1/triggers", shuffle.HandleGetTriggers).Methods("GET", "OPTIONS")
//r.HandleFunc("/api/v1/triggers/gmail/routing", handleGmailRouting).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/triggers/gmail/{key}", shuffle.HandleGetSpecificTrigger).Methods("GET", "OPTIONS")
@@ -4906,7 +5076,8 @@ func initHandlers() {
r.HandleFunc("/api/v1/orgs/{orgId}/change", shuffle.HandleChangeUserOrg).Methods("POST", "OPTIONS") // Swaps to the org
r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleDeleteOrg).Methods("DELETE", "OPTIONS")
-
+ r.HandleFunc("/api/v1/orgs/{orgId}/suborgs", shuffle.HandleGetSubOrgs).Methods("GET", "OPTIONS")
+
// This is a new API that validates if a key has been seen before.
// Not sure what the best course of action is for it.
r.HandleFunc("/api/v1/environments/{key}/stop", shuffle.HandleStopExecutions).Methods("GET", "POST", "OPTIONS")
@@ -4916,6 +5087,8 @@ func initHandlers() {
r.HandleFunc("/api/v1/orgs/{orgId}/list_cache", shuffle.HandleListCacheKeys).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}/get_cache", shuffle.HandleGetCacheKey).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}/set_cache", shuffle.HandleSetCacheKey).Methods("POST", "OPTIONS")
+ r.HandleFunc("/api/v1/orgs/{orgId}/delete_cache", shuffle.HandleDeleteCacheKeyPost).Methods("POST", "OPTIONS")
+ r.HandleFunc("/api/v1/orgs/{orgId}/cache/{cache_key}", shuffle.HandleDeleteCacheKey).Methods("DELETE", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}/stats", shuffle.HandleGetStatistics).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}/statistics", shuffle.HandleGetStatistics).Methods("GET", "OPTIONS")
@@ -4936,6 +5109,7 @@ func initHandlers() {
// PS: For cloud, this has to use cloud storage.
// https://developer.box.com/reference/get-files-id-content/
// 1. Creating the "get file" option. Make it possible to run this in the frontend.
+ r.HandleFunc("/api/v1/files/download_remote", shuffle.HandleDownloadRemoteFiles).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/files/namespaces/{namespace}", shuffle.HandleGetFileNamespace).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/files/{fileId}/content", shuffle.HandleGetFileContent).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/files/create", shuffle.HandleCreateFile).Methods("POST", "OPTIONS")
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index 659c52b3..10df25b2 100755
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -293,12 +293,35 @@ func handleGetWorkflowqueue(resp http.ResponseWriter, request *http.Request) {
env, err := shuffle.GetEnvironment(ctx, orgId, "")
timeNow := time.Now().Unix()
if err == nil && len(env.Id) > 0 && len(env.Name) > 0 {
+ // Updates every 60 seconds~
if time.Now().Unix() > env.Edited+60 {
- env.RunningIp = request.RemoteAddr
+ env.RunningIp = shuffle.GetRequestIp(request)
+ if len(orborusLabel) > 0 {
+ env.RunningIp = orborusLabel
+ }
+
+ if request.Method == "POST" {
+ body, err := ioutil.ReadAll(request.Body)
+ if err == nil {
+ var envData shuffle.OrborusStats
+ err = json.Unmarshal(body, &envData)
+ if err == nil {
+ if envData.Swarm {
+ env.Licensed = true
+ env.RunType = "docker"
+ }
+
+ if envData.Kubernetes {
+ env.RunType = "k8s"
+ }
+ }
+ }
+ }
+
env.Checkin = timeNow
err = shuffle.SetEnvironment(ctx, env)
if err != nil {
- log.Printf("[WARNING] Failed updating environment: %s", err)
+ log.Printf("[ERROR] Failed updating environment: %s", err)
}
}
}
@@ -552,7 +575,9 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) {
ctx := context.Background()
workflowExecution, err := shuffle.GetWorkflowExecution(ctx, actionResult.ExecutionId)
if err != nil {
- log.Printf("[WARNING][%s] Failed getting execution (streamresult): %s", actionResult.ExecutionId, err)
+ if len(actionResult.ExecutionId) > 0 {
+ log.Printf("[WARNING][%s] Failed getting execution (streamresult): %s", actionResult.ExecutionId, err)
+ }
resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad authorization key or execution_id might not exist."}`)))
return
@@ -952,42 +977,7 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) {
resp.Write([]byte(`{"success": true}`))
}
-// Identifies what a category defined really is
-func getWorkflowLocal(fileId string, request *http.Request) ([]byte, error) {
- fullUrl := fmt.Sprintf("%s/api/v1/workflows/%s", localBase, fileId)
- client := &http.Client{}
- req, err := http.NewRequest(
- "GET",
- fullUrl,
- nil,
- )
-
- if err != nil {
- return []byte{}, err
- }
-
- for key, value := range request.Header {
- req.Header.Add(key, strings.Join(value, ";"))
- }
-
- newresp, err := client.Do(req)
- if err != nil {
- return []byte{}, err
- }
-
- body, err := ioutil.ReadAll(newresp.Body)
- if err != nil {
- return []byte{}, err
- }
-
- // Temporary solution
- if strings.Contains(string(body), "reason") && strings.Contains(string(body), "false") {
- return []byte{}, errors.New(fmt.Sprintf("Failed getting workflow %s with message %s", fileId, string(body)))
- }
-
- return body, nil
-}
func handleExecution(id string, workflow shuffle.Workflow, request *http.Request, orgId string) (shuffle.WorkflowExecution, string, error) {
//go func() {
@@ -1777,7 +1767,7 @@ func cloudExecuteAction(execution shuffle.WorkflowExecution) error {
}
syncURL := fmt.Sprintf("%s/api/v1/cloud/sync/execute_node", syncUrl)
- client := &http.Client{}
+ client := shuffle.GetExternalClient(syncURL)
req, err := http.NewRequest(
"POST",
syncURL,
@@ -3216,6 +3206,12 @@ func setNewWorkflowApp(resp http.ResponseWriter, request *http.Request) {
workflowapp.Generated = false
workflowapp.Activated = true
+ if !shuffle.ArrayContains(workflowapp.Contributors, user.Id) {
+ workflowapp.Contributors = append(workflowapp.Contributors, user.Id)
+ }
+
+ shuffle.SetAppRevision(ctx, workflowapp)
+
err = shuffle.SetWorkflowAppDatastore(ctx, workflowapp, workflowapp.ID)
if err != nil {
log.Printf("[WARNING] Failed setting workflowapp: %s", err)
diff --git a/docker-compose.yml b/docker-compose.yml
index 63124856..2c50d5a1 100755
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,7 +1,7 @@
version: '3'
services:
frontend:
- image: ghcr.io/shuffle/shuffle-frontend:latest
+ image: ghcr.io/shuffle/shuffle-frontend:nightly
container_name: shuffle-frontend
hostname: shuffle-frontend
ports:
@@ -15,7 +15,7 @@ services:
depends_on:
- backend
backend:
- image: ghcr.io/shuffle/shuffle-backend:latest
+ image: ghcr.io/shuffle/shuffle-backend:nightly
container_name: shuffle-backend
hostname: ${BACKEND_HOSTNAME}
# Here for debugging:
@@ -34,7 +34,7 @@ services:
- SHUFFLE_FILE_LOCATION=/shuffle-files
restart: unless-stopped
orborus:
- image: ghcr.io/shuffle/shuffle-orborus:latest
+ image: ghcr.io/shuffle/shuffle-orborus:nightly
container_name: shuffle-orborus
hostname: shuffle-orborus
networks:
@@ -60,9 +60,10 @@ services:
security_opt:
- seccomp:unconfined
opensearch:
- image: opensearchproject/opensearch:2.11.0
+ image: opensearchproject/opensearch:2.14.0
hostname: shuffle-opensearch
container_name: shuffle-opensearch
+ env_file: .env
environment:
- "OPENSEARCH_JAVA_OPTS=-Xms2048m -Xmx2048m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
- bootstrap.memory_lock=true
@@ -73,6 +74,7 @@ services:
- node.name=shuffle-opensearch
- node.store.allow_mmap=false
- discovery.seed_hosts=shuffle-opensearch
+ - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${SHUFFLE_OPENSEARCH_PASSWORD}
ulimits:
memlock:
soft: -1
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
index 4bf5bf0b..e9d6d683 100755
--- a/frontend/Dockerfile
+++ b/frontend/Dockerfile
@@ -1,5 +1,5 @@
# Build environment
-FROM node:18 as builder
+FROM node:21 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
@@ -8,10 +8,10 @@ ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
# Nocache yarn install
-RUN yarn config set "strict-ssl" false -g
-RUN yarn install --network-timeout 1000000
+#RUN yarn config set "strict-ssl" false -g
+#RUN yarn install --network-timeout 1000000
-#RUN npm install
+RUN npm install --legacy-peer-deps
# copy only required files to not trigger rebuilding every time
COPY ./certs /usr/src/app/certs/
@@ -21,7 +21,8 @@ COPY ./*.sh /usr/src/app/
COPY ./*.json /usr/src/app/
#RUN rm -rf /usr/src/app/node_modules/webpack
-RUN yarn build
+#RUN yarn build --verbose
+RUN npm run build --loglevel verbose 2>&1
# Production environment
FROM nginx:1.21.5
diff --git a/frontend/enable_subpathing.sh b/frontend/enable_subpathing.sh
new file mode 100644
index 00000000..a6f76db4
--- /dev/null
+++ b/frontend/enable_subpathing.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Sekerovic Dragan, oneStep2 GmbH - 2023-09-08 - quick and dirty
+# purpose of the script: make shuffle reverse proxyable/run shuffle on a subpath instead of root
+
+if $(ls frontend/src/App.jsx.orig.* 1>/dev/null 2>&1); then
+ echo "shuffle src already patched for subpathing!"
+ echo "Aborting ..."
+ exit 1
+fi
+
+[[ "$1" != "" ]] && SUBPATH=$1 || SUBPATH="/shuffle"
+
+cat $0.tpl | sed "s,SUBPATH,$SUBPATH," > $0.run
+chmod 700 $0.run
+./$0.run
+rm ./$0.run
+
+exit 0
diff --git a/frontend/enable_subpathing.sh.tpl b/frontend/enable_subpathing.sh.tpl
new file mode 100644
index 00000000..04680e38
--- /dev/null
+++ b/frontend/enable_subpathing.sh.tpl
@@ -0,0 +1,139 @@
+#!/bin/bash
+
+cd frontend
+
+cd src
+cp App.jsx App.jsx.orig.`date -I`
+sed 's,startsWith("/,startsWith("SUBPATH/,g' -i App.jsx
+sed 's,path="/,path="SUBPATH/,g' -i App.jsx
+sed 's,location = "/,location = "SUBPATH/,g' -i App.jsx
+sed 's,window.location.origin;,"SUBPATH";,' -i App.jsx
+
+cd views
+for d in $(ls *.jsx); do cp $d $d.orig.`date -I`; done
+sed 's,pathname = "/,pathname = "SUBPATH/,g' -i *.jsx
+sed 's,navigate("/,navigate("SUBPATH/,g' -i *.jsx
+sed 's,navigate(`/,navigate(`SUBPATH/,g' -i *.jsx
+sed 's,href="/,href="SUBPATH/,g' -i *.jsx
+sed 's,path = "/,path = "SUBPATH/,g' -i *.jsx
+sed 's,link={"/,link={"SUBPATH/,g' -i *.jsx
+sed 's,to="/,to="SUBPATH/,g' -i *.jsx
+sed 's,to={"/,to={"SUBPATH/,g' -i *.jsx
+sed 's,${window.location.origin},SUBPATH,g' -i *.jsx
+cd ..
+
+cd components
+for d in $(ls *.jsx); do cp $d $d.orig.`date -I`; done
+sed 's,to="/,to="SUBPATH/,g' -i *.jsx
+sed 's,${window.location.origin},SUBPATH,g' -i *.jsx
+cd ../..
+
+cd confd/templates
+cp nginx.conf nginx.conf.orig.`date -I`
+sed 's,location / {,rewrite ^SUBPATH(/api/v1.*)$ $1 last;\n\n\t\tlocation / {,' -i nginx.conf
+cd ../..
+
+docker build -t ghcr.io/shuffle/shuffle-frontend:latest .
+
+
+cat << EOF
+
+If you want to reverse proxy shuffle using subpath "SUBPATH" you need to configure
+your web server - in this case nginx - to do the reverse proxying by at least adding
+
+ location SUBPATH {
+ proxy_pass http://snooss-proxy:3421/;
+ rewrite SUBPATH/(.*)$ /$1 break;
+
+ proxy_read_timeout 300s;
+
+ # proxy header
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+ # substitute html content response
+ proxy_set_header Accept-Encoding ""; # no compression allowed or sub_filter won't work
+ sub_filter 'href="/' 'href="SUBPATH/';
+ sub_filter 'href:"/' 'href:"SUBPATH/';
+ sub_filter '/static' 'SUBPATH/static';
+ sub_filter '/images' 'SUBPATH/images';
+ sub_filter_types *;
+ sub_filter_once off;
+ }
+
+to your nginx configuration.
+EOF
+
+
+exit 0#!/bin/bash
+
+cd frontend
+
+cd src
+cp App.jsx App.jsx.orig.`date -I`
+sed 's,startsWith("/,startsWith("SUBPATH/,g' -i App.jsx
+sed 's,path="/,path="SUBPATH/,g' -i App.jsx
+sed 's,location = "/,location = "SUBPATH/,g' -i App.jsx
+sed 's,window.location.origin;,"SUBPATH";,' -i App.jsx
+
+cd views
+for d in $(ls *.jsx); do cp $d $d.orig.`date -I`; done
+sed 's,pathname = "/,pathname = "SUBPATH/,g' -i *.jsx
+sed 's,navigate("/,navigate("SUBPATH/,g' -i *.jsx
+sed 's,navigate(`/,navigate(`SUBPATH/,g' -i *.jsx
+sed 's,href="/,href="SUBPATH/,g' -i *.jsx
+sed 's,path = "/,path = "SUBPATH/,g' -i *.jsx
+sed 's,link={"/,link={"SUBPATH/,g' -i *.jsx
+sed 's,to="/,to="SUBPATH/,g' -i *.jsx
+sed 's,to={"/,to={"SUBPATH/,g' -i *.jsx
+sed 's,${window.location.origin},SUBPATH,g' -i *.jsx
+cd ..
+
+cd components
+for d in $(ls *.jsx); do cp $d $d.orig.`date -I`; done
+sed 's,to="/,to="SUBPATH/,g' -i *.jsx
+sed 's,${window.location.origin},SUBPATH,g' -i *.jsx
+cd ../..
+
+cd confd/templates
+cp nginx.conf nginx.conf.orig.`date -I`
+sed 's,location / {,rewrite ^SUBPATH(/api/v1.*)$ $1 last;\n\n\t\tlocation / {,' -i nginx.conf
+cd ../..
+
+docker build -t ghcr.io/shuffle/shuffle-frontend:latest .
+
+
+cat << EOF
+
+If you want to reverse proxy shuffle using subpath "SUBPATH" you need to configure
+your web server - in this case nginx - to do the reverse proxying by at least adding
+
+ location SUBPATH {
+ proxy_pass http://snooss-proxy:3421/;
+ rewrite SUBPATH/(.*)$ /$1 break;
+
+ proxy_read_timeout 300s;
+
+ # proxy header
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+ # substitute html content response
+ proxy_set_header Accept-Encoding ""; # no compression allowed or sub_filter won't work
+ sub_filter 'href="/' 'href="SUBPATH/';
+ sub_filter 'href:"/' 'href:"SUBPATH/';
+ sub_filter '/static' 'SUBPATH/static';
+ sub_filter '/images' 'SUBPATH/images';
+ sub_filter_types *;
+ sub_filter_once off;
+ }
+
+to your nginx configuration.
+EOF
+
+
+exit 0
diff --git a/frontend/package.json b/frontend/package.json
index c6421d1b..635c079f 100755
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "shuffler",
"homepage": "https://shuffler.io",
- "version": "1.3.3",
+ "version": "1.4.0",
"private": true,
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
@@ -59,6 +59,7 @@
"mui-chips-input": "^2.1.3",
"mui-nested-menu": "^3.2.1",
"react": "^18.2.0",
+ "react-ace": "^10.1.0",
"react-alice-carousel": "^2.6.4",
"react-avatar-editor": "^11.1.0",
"react-beforeunload": "^2.2.1",
@@ -131,6 +132,7 @@
"babel-plugin-transform-imports": "^2.0.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
+ "postcss": "^8.4.38",
"promise-window": "^1.2.1",
"react-hot-loader": "^4.13.0",
"webpack-cli": "^5.1.4"
diff --git a/frontend/public/icons/docker.svg b/frontend/public/icons/docker.svg
new file mode 100644
index 00000000..297bb83f
--- /dev/null
+++ b/frontend/public/icons/docker.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/icons/k8s.svg b/frontend/public/icons/k8s.svg
new file mode 100644
index 00000000..bedd3b88
--- /dev/null
+++ b/frontend/public/icons/k8s.svg
@@ -0,0 +1,84 @@
+
+
+
+
diff --git a/frontend/public/images/no_image.png b/frontend/public/images/no_image.png
new file mode 100644
index 00000000..8c6937e2
Binary files /dev/null and b/frontend/public/images/no_image.png differ
diff --git a/frontend/public/images/social/resized/discord.png b/frontend/public/images/social/resized/discord.png
new file mode 100755
index 00000000..8873a34f
Binary files /dev/null and b/frontend/public/images/social/resized/discord.png differ
diff --git a/frontend/public/images/social/resized/github.png b/frontend/public/images/social/resized/github.png
new file mode 100755
index 00000000..77416ea9
Binary files /dev/null and b/frontend/public/images/social/resized/github.png differ
diff --git a/frontend/public/images/social/resized/twitter.png b/frontend/public/images/social/resized/twitter.png
new file mode 100755
index 00000000..46c8b3d7
Binary files /dev/null and b/frontend/public/images/social/resized/twitter.png differ
diff --git a/frontend/public/images/workflows/tenzir2.png b/frontend/public/images/workflows/tenzir2.png
new file mode 100644
index 00000000..12c702bc
Binary files /dev/null and b/frontend/public/images/workflows/tenzir2.png differ
diff --git a/frontend/public/images/workflows/user_input.svg b/frontend/public/images/workflows/user_input.svg
new file mode 100644
index 00000000..0ee42314
--- /dev/null
+++ b/frontend/public/images/workflows/user_input.svg
@@ -0,0 +1,30 @@
+
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index f2a79f65..dba2d5db 100755
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -56,10 +56,9 @@ if (window.location.port === "3000") {
// Development on Github Codespaces
if (globalUrl.includes("app.github.dev")) {
- //globalUrl = globalUrl.replace("3000", "5001")
- globalUrl = "https://frikky-shuffle-5gvr4xx62w64-5001.preview.app.github.dev"
+ globalUrl = globalUrl.replace("-3000.", "-5001.")
+ globalUrl = globalUrl.replace("-3001.", "-5001.")
}
-//console.log("global: ", globalUrl)
const App = (message, props) => {
@@ -177,34 +176,45 @@ const App = (message, props) => {
curpath={curpath}
setCurpath={setCurpath}
/>
- {!isLoaded ? null :
- userdata.chat_disabled === true ? null :
-
+ : null}
+ {isCloud && highlight === true && top_text !== "Base Cloud Access" ?
+ : null}
+ {isCloud && highlight === true && top_text !== "Base Cloud Access" ?
+