Added single app testing from GUI

This commit is contained in:
frikky
2021-06-02 23:39:20 +02:00
parent 2c9bac9eb0
commit 24fd96fcf0
10 changed files with 83 additions and 58 deletions
+6 -6
View File
@@ -1967,12 +1967,12 @@ class AppBase:
params[parameter["name"]] = resultarray
multi_parameters[parameter["name"]] = resultarray
if len(resultarray) == 0:
print("[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
#if len(resultarray) == 0:
# print("[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
multi_execution_lists.append(new_replacement)
#print("MULTI finished: %s" % json_replacement)
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
NAME=shuffle-app_sdk
VERSION=0.8.97
VERSION=0.8.98
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
+14 -18
View File
@@ -3177,7 +3177,7 @@ func handleSwaggerValidation(body []byte) (shuffle.ParsedOpenApi, error) {
//log.Printf("Json err: %s", err)
err = yaml.Unmarshal(body, &version)
if err != nil {
log.Printf("Yaml error (1): %s", err)
log.Printf("[WARNING] Yaml error (1): %s", err)
} else {
//log.Printf("Successfully parsed YAML!")
}
@@ -3220,7 +3220,7 @@ func handleSwaggerValidation(body []byte) (shuffle.ParsedOpenApi, error) {
//log.Printf("Json error? %s", err)
err = yaml.Unmarshal(body, &swagger)
if err != nil {
log.Printf("Yaml error (2): %s", err)
log.Printf("[WARNING] Yaml error (2): %s", err)
return shuffle.ParsedOpenApi{}, err
} else {
//log.Printf("Valid yaml!")
@@ -4181,14 +4181,14 @@ func runInitEs(ctx context.Context) {
for _, org := range activeOrgs {
if !org.CloudSync {
log.Printf("Skipping org %s because sync isn't set (1).", org.Id)
log.Printf("[WARNING] Skipping org %s because sync isn't set (1).", org.Id)
continue
}
//interval := int(org.SyncConfig.Interval)
interval := 15
if interval == 0 {
log.Printf("Skipping org %s because sync isn't set (0).", org.Id)
log.Printf("[WARNING] Skipping org %s because sync isn't set (0).", org.Id)
continue
}
@@ -4204,7 +4204,7 @@ func runInitEs(ctx context.Context) {
if err != nil {
log.Printf("[CRITICAL] Failed to schedule org: %s", err)
} else {
log.Printf("Started sync on interval %d for org %s", interval, org.Name)
log.Printf("[INFO] Started sync on interval %d for org %s (%s)", interval, org.Name, org.Id)
scheduledOrgs[org.Id] = jobret
}
}
@@ -5035,7 +5035,7 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error)
return &org, errors.New(fmt.Sprintf("Couldn't find any sync key to disable org %s", org.Id))
}
log.Printf("Should run cloud sync disable for org %s with URL %s and sync key %s", org.Id, syncUrl, org.SyncConfig.Apikey)
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{}
req, err := http.NewRequest(
@@ -5071,7 +5071,7 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error)
return &org, errors.New(responseData.Reason)
}
log.Printf("Everything is success. Should disable org sync for %s", org.Id)
log.Printf("[INFO] Everything is success. Should disable org sync for %s", org.Id)
ctx := context.Background()
org.CloudSync = false
@@ -5080,15 +5080,14 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error)
err = shuffle.SetOrg(ctx, org, org.Id)
if err != nil {
newerror := fmt.Sprintf("ERROR: Failed updating even though there was success: %s", err)
newerror := fmt.Sprintf("[WARNING] ERROR: Failed updating even though there was success: %s", err)
log.Printf(newerror)
return &org, errors.New(newerror)
}
var environments []shuffle.Environment
q := datastore.NewQuery("Environments").Filter("org_id =", org.Id)
_, err = dbclient.GetAll(ctx, q, &environments)
environments, err := shuffle.GetEnvironments(ctx, org.Id)
if err != nil {
log.Printf("[WARNING] Failed getting envs in stop sync: %s", err)
return &org, err
}
@@ -5237,9 +5236,9 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
// Everything below here is to SET UP CLOUD SYNC.
// If you want to disable cloud sync, see previous section.
if org.CloudSync {
log.Printf("Org %s is already syncing. Skip", org.Id)
log.Printf("[WARNING] Org %s is already syncing. Skip", org.Id)
resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Org is already syncing. Nothing to set up."}`)))
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Your org is already syncing. Nothing to set up."}`)))
return
}
@@ -5332,18 +5331,15 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
scheduledOrgs[org.Id] = jobret
}
// FIXME: Add this for every feature
// ONLY checked added if workflows are allow huh
if org.SyncFeatures.Workflows.Active {
log.Printf("[INFO] Should activate cloud workflows for org %s!", org.Id)
// 1. Find environment
// 2. If cloud env found, enable it (un-archive)
// 3. If it doesn't create it
//var environments []shuffle.Environment
//q := datastore.NewQuery("Environments").Filter("org_id =", org.Id)
//_, err = dbclient.GetAll(ctx, q, &environments)
environments, err := shuffle.GetEnvironments(ctx, org.Id)
log.Printf("GETTING ENVS: %#s", environments)
if err == nil {
// Don't disable, this will be deleted entirely
+6 -6
View File
@@ -1179,10 +1179,10 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) {
}
}
err = increaseStatisticsField(ctx, "total_workflow_triggers", workflow.ID, -1, workflow.OrgId)
if err != nil {
log.Printf("Failed to increase total workflows: %s", err)
}
//err = increaseStatisticsField(ctx, "total_workflow_triggers", workflow.ID, -1, workflow.OrgId)
//if err != nil {
// log.Printf("Failed to increase total workflows: %s", err)
//}
}
// FIXME - maybe delete workflow executions
@@ -3408,14 +3408,14 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string,
readFile, err := ioutil.ReadAll(fileReader)
if err != nil {
log.Printf("Filereader error yaml for %s: %s", filename, err)
log.Printf("[WARNING] Filereader error yaml for %s: %s", filename, err)
continue
}
// 1. This parses OpenAPI v2 to v3 etc, for use.
parsedOpenApi, err := handleSwaggerValidation(readFile)
if err != nil {
log.Printf("Validation error for %s: %s", filename, err)
log.Printf("[WARNING] Validation error for %s: %s", filename, err)
continue
}
+1 -1
View File
@@ -115,8 +115,8 @@ const App = (message, props) => {
<Route exact path="/webhooks/:key" render={props => <EditWebhook isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
<Route exact path="/schedules" render={props => <Schedules globalUrl={globalUrl} {...props} />} />
<Route exact path="/dashboard" render={props => <Dashboard isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
<Route exact path="/apps" render={props => <Apps isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} userdata={userdata} {...props} />} />
<Route exact path="/apps/new" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
<Route exact path="/apps" render={props => <Apps isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} userdata={userdata} {...props} />} />
<Route exact path="/apps/edit/:appid" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
<Route exact path="/schedules/:key" render={props => <EditSchedule globalUrl={globalUrl} {...props} />} />
<Route exact path="/workflows" render={props => <Workflows cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} cookies={cookies} userdata={userdata} {...props} />} />
+25
View File
@@ -50,6 +50,7 @@ const ParsedAction = (props) => {
const theme = useTheme();
const classes = useStyles()
const keywords = ["len(", "lower(", "upper(", "trim(", "split(", "length(", "number(", "parse(", "join("]
const getParents = (action) => {
if (cy === undefined) {
return []
@@ -757,6 +758,23 @@ const ParsedAction = (props) => {
}}
/>
console.log("FIELD VALUE: ", data.value)
//const regexp = new RegExp("\W+\.", "g")
//let match
//while ((match = regexp.exec(data.value)) !== null) {
// console.log(`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`);
//}
//const str = = data.value.search(submatch)
//console.log("FOUND? ", n)
for (var key in keywords) {
const keyword = keywords[key]
if (data.value.includes(keyword)) {
console.log("INCLUDED: ", keyword)
}
}
//const keywords = ["len", "lower", "upper", "trim", "split", "length", "number", "parse", "join"]
if (selectedActionParameters[count].schema !== undefined && selectedActionParameters[count].schema !== null && selectedActionParameters[count].schema.type === "file") {
datafield =
<TextField
@@ -875,7 +893,11 @@ const ParsedAction = (props) => {
return
}
console.log("AUTOCOMPLETE1: ", values)
var toComplete = selectedActionParameters[count].value.trim().endsWith("$") ? values[0].autocomplete : "$"+values[0].autocomplete
toComplete = toComplete.toLowerCase().replaceAll(" ", "_")
console.log("AUTOCOMPLETE: ", toComplete)
for (var key in values) {
if (key == 0 || values[key].autocomplete.length === 0) {
continue
@@ -1353,6 +1375,9 @@ const ParsedAction = (props) => {
}
}
}
console.log("DID REPLACE ACTUALLY WORK?? - Something is buggy.")
setWorkflow(workflow)
}}
/>
</span>
+11 -10
View File
@@ -154,7 +154,7 @@ const Admin = (props) => {
// Need to wait because query in ES is too fast
setTimeout(() => {
getAppAuthentication()
}, 1000)
}, 500)
alert.success("Successfully deleted authentication!")
}
}),
@@ -228,7 +228,7 @@ const Admin = (props) => {
.then((responseJson) => {
setTimeout(() => {
handleGetOrg(org_id)
}, 1000)
}, 500)
})
.catch(error => {
alert.error("Err: " + error.toString())
@@ -264,12 +264,13 @@ const Admin = (props) => {
console.log("Cloud sync fail?")
}
setTimeout(() => {
return response.json()
}, 1000)
return response.json()
//setTimeout(() => {
//}, 1000)
})
.then((responseJson) => {
if (!responseJson.success && responseJson.reason !== undefined) {
console.log("RESP: ", responseJson)
if (responseJson.success === false && responseJson.reason !== undefined) {
setOrgSyncResponse(responseJson.reason)
alert.error("Failed to handle sync: "+responseJson.reason)
} else if (!responseJson.success) {
@@ -355,7 +356,7 @@ const Admin = (props) => {
setSelectedUserModalOpen(false)
setTimeout(() => {
getAppAuthentication()
}, 1000)
}, 500)
}
}),
)
@@ -513,7 +514,7 @@ const Admin = (props) => {
setModalOpen(false)
setTimeout(() => {
getUsers()
}, 1000)
}, 500)
}
}),
)
@@ -548,7 +549,7 @@ const Admin = (props) => {
setModalOpen(false)
setTimeout(() => {
getUsers()
}, 1000)
}, 500)
}
}),
)
@@ -1649,7 +1650,7 @@ const Admin = (props) => {
</div>
{orgSyncResponse.length > 0 ?
<Typography style={{marginTop: 5, marginBottom: 10}}>
Message from Shuffle: <b>{orgSyncResponse}</b>
Message from Shuffle Cloud: <b>{orgSyncResponse}</b>
</Typography>
: null
}
+11 -11
View File
@@ -1571,17 +1571,13 @@ const AngularWorkflow = (props) => {
}
}
console.log("ID ETC: ", idnumber, paramname)
if (idnumber >= 0 && paramname.length > 0) {
const exampledata = GetExampleResult(nodedata)
const parsedname = paramname.toLowerCase().trim().replaceAll("_", " ")
console.log("EX: ", exampledata)
console.log("NAME: ", parsedname)
const foundresult = GetParamMatch(parsedname, exampledata, "")
console.log("RESULT: ", foundresult)
if (foundresult.length > 0) {
console.log("FOUND: ", paramname, foundresult)
console.log("FOUND RESULT: ", paramname, foundresult)
newValue = `${newValue}${foundresult}`
}
@@ -2100,9 +2096,13 @@ const AngularWorkflow = (props) => {
return ""
}
if (exampledata === null) {
return ""
}
// Basically just a stupid if-else :)
const synonyms = {
"id": ["id", "ref", "sourceref", "reference", "sourcereference", "alert id", "case id", "incident id", "service id",],
"id": ["id", "ref", "sourceref", "reference", "sourcereference", "alert id", "case id", "incident id", "service id", "sid", "uid", "uuid"],
"title": ["title", "name", "message"],
"description": ["description", "explanation", "story", "details",],
"email": ["mail", "email", "sender", "receiver", "recipient"],
@@ -7535,7 +7535,7 @@ const AngularWorkflow = (props) => {
/* Copy the text inside the text field */
document.execCommand("copy")
alert.success("Copied data")
//alert.success("Copied data")
} else {
console.log("Failed to copy from "+elementName+": ", copyText)
}
@@ -7544,7 +7544,7 @@ const AngularWorkflow = (props) => {
const HandleJsonCopy = (base, copy, base_node_name) => {
console.log("COPY: ", copy)
var newitem = JSON.parse(base)
to_be_copied = "$"+base_node_name
to_be_copied = "$"+base_node_name.toLowerCase().replaceAll(" ", "_")
for (var key in copy.namespace) {
if (copy.namespace[key].includes("Results for")) {
continue
@@ -7591,7 +7591,7 @@ const AngularWorkflow = (props) => {
/* Copy the text inside the text field */
document.execCommand("copy");
alert.success("Copied "+to_be_copied)
//alert.success("Copied "+to_be_copied)
console.log("COPYING!")
} else {
console.log("Couldn't find element ", elementName)
@@ -8097,7 +8097,7 @@ const AngularWorkflow = (props) => {
{validate.valid ? <ReactJson
src={validate.result}
theme="solarized"
collapsed={false}
collapsed={selectedResult.result.length < 10000 ? false : true}
displayDataTypes={false}
enableClipboard={(copy) => {
handleReactJsonClipboard(copy)
@@ -8131,7 +8131,7 @@ const AngularWorkflow = (props) => {
/* Copy the text inside the text field */
document.execCommand("copy");
alert.success("Copied "+to_be_copied)
//alert.success("Copied "+to_be_copied)
} else {
console.log("Failed to copy. copy_element_shuffle is undefined")
}
+4 -3
View File
@@ -2443,7 +2443,7 @@ const AppCreator = (props) => {
version: selectedAction.app_version,
})
const [requiresAuthentication, setRequiresAuthentication] = useState(app.authentication.required && app.authentication.parameters !== undefined && app.authentication.parameters !== null)
const [requiresAuthentication, setRequiresAuthentication] = useState(app.authentication !== null && app.authentication !== undefined && app.authentication.required && app.authentication.parameters !== undefined && app.authentication.parameters !== null ? true : false)
const [workflow, setWorkflow] = useState({
name: "",
description: "",
@@ -2699,7 +2699,7 @@ const AppCreator = (props) => {
for (var key in selectedApp.authentication.parameters) {
if (authenticationOption.fields[selectedApp.authentication.parameters[key].name].length === 0) {
alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty")
return
return null
}
}
@@ -2744,6 +2744,7 @@ const AppCreator = (props) => {
authenticationOption.label = selectedApp.name+" authentication"
}
console.log("PRE RETURN")
return (
<div>
<DialogContent>
@@ -3032,7 +3033,7 @@ const AppCreator = (props) => {
Continue
</Button>
</DialogActions>
<ParsedActionHandler />
{/*<ParsedActionHandler />*/}
</FormControl>
</Dialog>
: null;
+4 -2
View File
@@ -531,7 +531,7 @@ const Workflows = (props) => {
deleteWorkflow(selectedWorkflowId)
setTimeout(() => {
getAvailableWorkflows()
}, 1000)
}, 500)
}
setDeleteModalOpen(false)
}} color="primary">
@@ -1489,7 +1489,9 @@ const Workflows = (props) => {
window.location.pathname = "/workflows/"+responseJson["id"]
} else if (!redirect) {
// Update :)
getAvailableWorkflows()
setTimeout(() => {
getAvailableWorkflows()
}, 500)
setImportLoading(false)
} else {
alert.info("Successfully changed basic info for workflow")