Bugfixes towards blogpost 4

This commit is contained in:
frikky
2020-06-23 20:04:00 +02:00
parent d4cbccd47e
commit 0d17de238b
10 changed files with 86 additions and 47 deletions
+6 -6
View File
@@ -4,13 +4,13 @@ ENVIRONMENT_NAME=Shuffle
# Remote github config for first load # Remote github config for first load
APP_DOWNLOAD_LOCATION=https://github.com/frikky/shuffle-apps APP_DOWNLOAD_LOCATION=https://github.com/frikky/shuffle-apps
APP_DOWNLOAD_AUTH_USERNAME="" APP_DOWNLOAD_AUTH_USERNAME=
APP_DOWNLOAD_AUTH_PASSWORD="" APP_DOWNLOAD_AUTH_PASSWORD=
# User config for first load # User config for first load. Username & PW: min length 3
SHUFFLE_DEFAULT_USERNAME="" SHUFFLE_DEFAULT_USERNAME=
SHUFFLE_DEFAULT_PASSWORD="" SHUFFLE_DEFAULT_PASSWORD=
SHUFFLE_DEFAULT_APIKEY="" SHUFFLE_DEFAULT_APIKEY=
# Local location of your app directory. Can't use ~/ # Local location of your app directory. Can't use ~/
APP_HOTLOAD_LOCATION=./shuffle-apps APP_HOTLOAD_LOCATION=./shuffle-apps
+23 -7
View File
@@ -384,14 +384,27 @@ class AppBase:
if value == "#": if value == "#":
# FIXME - not recursive - should go deeper if there are more # # FIXME - not recursive - should go deeper if there are more #
print("HANDLE RECURSIVE LOOP ") print("HANDLE RECURSIVE LOOP OF %s" % basejson)
returnlist = [] returnlist = []
try:
for innervalue in basejson: for innervalue in basejson:
#print("Value: %s" % value[parsersplit[cnt+1]]) print("Value: %s" % value[parsersplit[cnt+1]])
returnlist.append(innervalue[parsersplit[cnt+1]]) returnlist.append(innervalue[parsersplit[cnt+1]])
except IndexError as e:
print("Indexerror inner: %s" % e)
# Basically means its a normal list, not a crazy one :)
# Custom format for ${name[0,1,2,...]}$
indexvalue = "${NO_SPLITTER%s}$" % json.dumps(basejson)
if len(returnlist) > 0:
indexvalue = "${NO_SPLITTER%s}$" % json.dumps(returnlist)
print("INDEXVAL: ", indexvalue)
return indexvalue
# Example format: ${[]}$ # Example format: ${[]}$
return "${%s%s}$" % (parsersplit[cnt+1], json.dumps(returnlist)) parseditem = "${%s%s}$" % (parsersplit[cnt+1], json.dumps(returnlist))
print("PARSED LOOP ITEM: %s" % parseditem)
return parseditem
else: else:
if isinstance(basejson[value], str): if isinstance(basejson[value], str):
@@ -405,9 +418,8 @@ class AppBase:
basejson = basejson[value] basejson = basejson[value]
except KeyError as e: except KeyError as e:
print("Lower keyerror: %s" % e)
return "KeyError: %s" % e return "KeyError: %s" % e
except IndexError as e:
return "IndexError: %s" % e
return basejson return basejson
@@ -424,7 +436,7 @@ class AppBase:
#self.logger.debug(f"\n\nHandle static data with JSON: {data}\n\n") #self.logger.debug(f"\n\nHandle static data with JSON: {data}\n\n")
#self.logger.info("STATIC PARSED: %s" % actualitem) #self.logger.info("STATIC PARSED: %s" % actualitem)
if len(actualitem) > 0: if len(actualitem) > 0:
print("ACTUAL: %s", actualitem) print("ACTUAL: ", actualitem)
for replace in actualitem: for replace in actualitem:
try: try:
to_be_replaced = replace[0] to_be_replaced = replace[0]
@@ -488,8 +500,10 @@ class AppBase:
else: else:
fullname += parameter["action_field"] fullname += parameter["action_field"]
self.logger.info("PRE Fullname: %s" % fullname)
if parameter["value"].startswith(jsonparsevalue): if parameter["value"].startswith(jsonparsevalue):
fullname += parameter["value"][2:] fullname += parameter["value"][1:]
#else: #else:
# fullname = "$%s" % parameter["action_field"] # fullname = "$%s" % parameter["action_field"]
@@ -699,8 +713,10 @@ class AppBase:
raise "Value check error: %s" % Exception(check) raise "Value check error: %s" % Exception(check)
# Custom format for ${name[0,1,2,...]}$ # Custom format for ${name[0,1,2,...]}$
#submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})"
submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})" submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})"
actualitem = re.findall(submatch, value, re.MULTILINE) actualitem = re.findall(submatch, value, re.MULTILINE)
print("Multicheck: %s", actualitem)
if len(actualitem) > 0: if len(actualitem) > 0:
multiexecution = True multiexecution = True
+17 -13
View File
@@ -812,8 +812,8 @@ func parseLoginParameters(resp http.ResponseWriter, request *http.Request) (logi
// Removed for localhost // Removed for localhost
func checkPasswordStrength(password string) error { func checkPasswordStrength(password string) error {
// Check password strength here // Check password strength here
if len(password) < 10 { if len(password) < 3 {
return errors.New("Minimum password length is 10.") return errors.New("Minimum password length is 3.")
} }
//if len(password) > 128 { //if len(password) > 128 {
@@ -923,8 +923,8 @@ func checkUsername(Username string) error {
// return errors.New("Invalid Username") // return errors.New("Invalid Username")
//} //}
if len(Username) < 4 { if len(Username) < 3 {
return errors.New("Minimum Username length is 4") return errors.New("Minimum Username length is 3")
} }
return nil return nil
@@ -1939,7 +1939,7 @@ func handlePasswordChange(resp http.ResponseWriter, request *http.Request) {
if len(users) != 1 { if len(users) != 1 {
log.Printf(`Found multiple users with the same username: %s: %d`, t.Username, len(users)) log.Printf(`Found multiple users with the same username: %s: %d`, t.Username, len(users))
resp.WriteHeader(401) resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Found multiple users with the same username: %s"}`, t.Username))) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Found %d users with the same username: %s (%d)"}`, len(users), t.Username)))
return return
} }
@@ -2233,7 +2233,8 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) {
} }
ctx := context.Background() ctx := context.Background()
q := datastore.NewQuery("Users").Filter("Username =", strings.ToLower(data.Username)) log.Printf("Username: %s", data.Username)
q := datastore.NewQuery("Users").Filter("Username =", data.Username)
var users []User var users []User
_, err = dbclient.GetAll(ctx, q, &users) _, err = dbclient.GetAll(ctx, q, &users)
if err != nil { if err != nil {
@@ -2246,7 +2247,7 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) {
if len(users) != 1 { if len(users) != 1 {
log.Printf(`Found multiple users with the same username: %s: %d`, data.Username, len(users)) log.Printf(`Found multiple users with the same username: %s: %d`, data.Username, len(users))
resp.WriteHeader(401) resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Found multiple users with the same username: %s"}`, data.Username))) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Found %d users with the same username: %s"}`, len(users), data.Username)))
return return
} }
@@ -3215,8 +3216,6 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
Running: false, Running: false,
} }
log.Printf("Hello")
// FIXME: Add cloud function execution? // FIXME: Add cloud function execution?
//b, err := json.Marshal(hook) //b, err := json.Marshal(hook)
//if err != nil { //if err != nil {
@@ -6140,7 +6139,6 @@ func runInit(ctx context.Context) {
} }
// Fix active users etc // Fix active users etc
log.Printf("Checking users")
q := datastore.NewQuery("Users").Filter("active =", true) q := datastore.NewQuery("Users").Filter("active =", true)
var activeusers []User var activeusers []User
_, err = dbclient.GetAll(ctx, q, &activeusers) _, err = dbclient.GetAll(ctx, q, &activeusers)
@@ -6181,18 +6179,23 @@ func runInit(ctx context.Context) {
} }
} }
} else if len(users) == 0 { } else if len(users) == 0 {
log.Printf("Trying to set up user based on environments DEFAULT_USERNAME & DEFAULT_PASSWORD") log.Printf("Trying to set up user based on environments SHUFFLE_DEFAULT_USERNAME & SHUFFLE_DEFAULT_PASSWORD")
username := os.Getenv("SHUFFLE_DEFAULT_USERNAME") username := os.Getenv("SHUFFLE_DEFAULT_USERNAME")
password := os.Getenv("SHUFFLE_DEFAULT_PASSWORD") password := os.Getenv("SHUFFLE_DEFAULT_PASSWORD")
if len(username) == 0 || len(password) == 0 { if len(username) == 0 || len(password) == 0 {
log.Printf("DEFAULT_USERNAME and DEFAULT_PASSWORD not defined as environments. Running without default user.") log.Printf("SHUFFLE_DEFAULT_USERNAME and SHUFFLE_DEFAULT_PASSWORD not defined as environments. Running without default user.")
} else { } else {
apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY") apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY")
err = createNewUser(username, password, "admin", apikey) err = createNewUser(username, password, "admin", apikey)
if err != nil { if err != nil {
log.Printf("Failed to create default user %s: %s", username, err) log.Printf("Failed to create default user %s: %s", username, err)
} else {
log.Printf("Successfully created user %s", username)
} }
} }
} else {
//log.Printf("Found %d users.", len(users))
//log.Printf(users[0].Username)
} }
} }
@@ -6306,7 +6309,7 @@ func runInit(ctx context.Context) {
} }
_, err = git.Clone(storer, fs, cloneOptions) _, err = git.Clone(storer, fs, cloneOptions)
if err != nil { if err != nil {
log.Printf("Failed loading repo %s into memory: %s", err) log.Printf("Failed loading repo %s into memory: %s", apis, err)
} else { } else {
log.Printf("Finished git clone. Looking for updates to the repo.") log.Printf("Finished git clone. Looking for updates to the repo.")
dir, err := fs.ReadDir("") dir, err := fs.ReadDir("")
@@ -6354,6 +6357,7 @@ func init() {
r.HandleFunc("/api/v1/users/getsettings", handleSettings).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users/getsettings", handleSettings).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/users/updateuser", handleUpdateUser).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/users/updateuser", handleUpdateUser).Methods("PUT", "OPTIONS")
r.HandleFunc("/api/v1/users/{user}", deleteUser).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/users/{user}", deleteUser).Methods("DELETE", "OPTIONS")
r.HandleFunc("/api/v1/users/passwordchange", handlePasswordChange).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/users", handleGetUsers).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users", handleGetUsers).Methods("GET", "OPTIONS")
// General - duplicates and old. // General - duplicates and old.
+12 -4
View File
@@ -1205,6 +1205,13 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) {
// Adds the Testing app if it's a new workflow // Adds the Testing app if it's a new workflow
workflowapps, err := getAllWorkflowApps(ctx) workflowapps, err := getAllWorkflowApps(ctx)
if err == nil { if err == nil {
// FIXME: Add real env
//q := datastore.NewQuery("Environments").Limit(1)
//count, err := dbclient.Get(ctx, q)
//envName := "Shuffle"
//if err == nil {
//}
for _, item := range workflowapps { for _, item := range workflowapps {
if item.Name == "Testing" && item.AppVersion == "1.0.0" { if item.Name == "Testing" && item.AppVersion == "1.0.0" {
nodeId := "40447f30-fa44-4a4f-a133-4ee710368737" nodeId := "40447f30-fa44-4a4f-a133-4ee710368737"
@@ -1627,10 +1634,10 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
} }
// Has to NOT be generated // Has to NOT be generated
//if app.Name == action.AppName && app.AppVersion == action.AppVersion { if app.Name == action.AppName && app.AppVersion == action.AppVersion {
// curapp = app curapp = app
// break break
//} }
} }
// Check to see if the whole app is valid // Check to see if the whole app is valid
@@ -1985,6 +1992,7 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
} }
// FIXME - this should have "execution_argument" from executeWorkflow frontend // FIXME - this should have "execution_argument" from executeWorkflow frontend
log.Printf("EXEC: %#v", execution)
if len(execution.ExecutionArgument) > 0 { if len(execution.ExecutionArgument) > 0 {
workflowExecution.ExecutionArgument = execution.ExecutionArgument workflowExecution.ExecutionArgument = execution.ExecutionArgument
} }
+3 -3
View File
@@ -14,7 +14,7 @@ services:
depends_on: depends_on:
- backend - backend
backend: backend:
#build: ./backend build: ./backend
image: frikky/shuffle:backend image: frikky/shuffle:backend
container_name: shuffle-backend container_name: shuffle-backend
hostname: ${BACKEND_HOSTNAME} hostname: ${BACKEND_HOSTNAME}
@@ -27,10 +27,10 @@ services:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- ${APP_HOTLOAD_LOCATION}:/shuffle-apps - ${APP_HOTLOAD_LOCATION}:/shuffle-apps
environment: environment:
- ORG_ID=${ORG_ID}
- DATASTORE_EMULATOR_HOST=shuffle-database:8000 - DATASTORE_EMULATOR_HOST=shuffle-database:8000
- APP_DOWNLOAD_LOCATION=${APP_DOWNLOAD_LOCATION}
- APP_HOTLOAD_FOLDER=/shuffle-apps - APP_HOTLOAD_FOLDER=/shuffle-apps
- ORG_ID=${ORG_ID}
- APP_DOWNLOAD_LOCATION=${APP_DOWNLOAD_LOCATION}
- SHUFFLE_DEFAULT_USERNAME=${SHUFFLE_DEFAULT_USERNAME} - SHUFFLE_DEFAULT_USERNAME=${SHUFFLE_DEFAULT_USERNAME}
- SHUFFLE_DEFAULT_PASSWORD=${SHUFFLE_DEFAULT_PASSWORD} - SHUFFLE_DEFAULT_PASSWORD=${SHUFFLE_DEFAULT_PASSWORD}
- SHUFFLE_DEFAULT_APIKEY=${SHUFFLE_DEFAULT_APIKEY} - SHUFFLE_DEFAULT_APIKEY=${SHUFFLE_DEFAULT_APIKEY}
+1 -1
View File
@@ -94,7 +94,7 @@ const Admin = (props) => {
}), }),
) )
.catch(error => { .catch(error => {
alert.error("Err: ", error.toString()) alert.error("Err: "+error.toString())
}); });
} }
+9 -7
View File
@@ -792,11 +792,12 @@ const AngularWorkflow = (props) => {
setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"])) setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"]))
setSelectedEdge(event.target.data()) setSelectedEdge(event.target.data())
setSelectedAction({})
setSelectedTrigger({})
} else { } else {
//alert.info("Can't edit branches from triggers") //alert.info("Can't edit branches from triggers")
} }
setSelectedAction({})
setSelectedTrigger({})
} }
const onNodeSelect = (event) => { const onNodeSelect = (event) => {
@@ -862,6 +863,7 @@ const AngularWorkflow = (props) => {
found = true found = true
break break
} else if (workflow.branches[key].destination_id === edge.target && workflow.branches[key].source_id === edge.source) { } else if (workflow.branches[key].destination_id === edge.target && workflow.branches[key].source_id === edge.source) {
console.log(edge)
alert.error("That branch already exists") alert.error("That branch already exists")
event.target.remove() event.target.remove()
found = true found = true
@@ -2485,13 +2487,13 @@ const AngularWorkflow = (props) => {
}} }}
style={{backgroundColor: inputColor, color: "white", height: "50px"}} style={{backgroundColor: inputColor, color: "white", height: "50px"}}
> >
{workflow.workflow_variables !== null ? workflow.workflow_variables.map(data => ( {workflow.workflow_variables !== undefined && workflow.workflow_variables !== null ? workflow.workflow_variables.map(data => (
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data.name}> <MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data.name}>
{data.name} {data.name}
</MenuItem> </MenuItem>
)) : null} )) : null}
<Divider /> <Divider />
{workflow.execution_variables !== null ? workflow.execution_variables.map(data => ( {workflow.execution_variables !== undefined && workflow.execution_variables !== null ? workflow.execution_variables.map(data => (
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data.name}> <MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data.name}>
{data.name} {data.name}
</MenuItem> </MenuItem>
@@ -2649,7 +2651,7 @@ const AngularWorkflow = (props) => {
placeholder={selectedAction.label} placeholder={selectedAction.label}
onChange={selectedNameChange} onChange={selectedNameChange}
/> />
{environments !== undefined && environments !== null && environments.length > 1 ? {environments !== undefined && environments !== null && environments.length > 0 ?
<div style={{marginTop: "20px"}}> <div style={{marginTop: "20px"}}>
Environment Environment
<Select <Select
@@ -3983,10 +3985,10 @@ const AngularWorkflow = (props) => {
if (responseJson.success) { if (responseJson.success) {
// Set the status // Set the status
alert.success("Successfully started webhook") alert.success("Successfully started webhook")
workflow.triggers[selectedTriggerIndex].status = "running"
trigger.status = "running" trigger.status = "running"
setWorkflow(workflow)
setSelectedTrigger(trigger) setSelectedTrigger(trigger)
workflow.triggers[selectedTriggerIndex].status = "running"
setWorkflow(workflow)
saveWorkflow(workflow) saveWorkflow(workflow)
} else { } else {
alert.error("Failed starting webhook: "+responseJson.reason) alert.error("Failed starting webhook: "+responseJson.reason)
+2
View File
@@ -111,6 +111,8 @@ const data = [{
selector: 'node:selected', selector: 'node:selected',
css: { css: {
'background-color': '#77b0d0', 'background-color': '#77b0d0',
'border-color': '#77b0d0',
'border-width': '20px',
}, },
}, },
{ {
+3 -2
View File
@@ -455,13 +455,14 @@ func zombiecheck() error {
continue continue
} }
if container.State != "running" { // Need to check time here too because a container can be removed the same instant as its created
currenttime := time.Now().Unix()
if container.State != "running" && currenttime-container.Created > int64(workerTimeout) {
removeContainers = append(removeContainers, container.ID) removeContainers = append(removeContainers, container.ID)
containerNames[container.ID] = name containerNames[container.ID] = name
} }
// stopcontainer & removecontainer // stopcontainer & removecontainer
currenttime := time.Now().Unix()
//log.Printf("Time: %d - %d", currenttime-container.Created, int64(workerTimeout)) //log.Printf("Time: %d - %d", currenttime-container.Created, int64(workerTimeout))
if container.State == "running" && currenttime-container.Created > int64(workerTimeout) { if container.State == "running" && currenttime-container.Created > int64(workerTimeout) {
stopContainers = append(stopContainers, container.ID) stopContainers = append(stopContainers, container.ID)
+7 -1
View File
@@ -423,6 +423,11 @@ func handleExecution(client *http.Client, req *http.Request, workflowExecution W
onpremApps := []string{} onpremApps := []string{}
startAction := workflowExecution.Start startAction := workflowExecution.Start
if len(startAction) == 0 {
log.Printf("Didn't find execution start action. Setting it to workflow start action.")
startAction = workflowExecution.Workflow.Start
}
log.Printf("Startaction: %s", startAction) log.Printf("Startaction: %s", startAction)
toExecuteOnprem := []string{} toExecuteOnprem := []string{}
parents := map[string][]string{} parents := map[string][]string{}
@@ -660,7 +665,7 @@ func handleExecution(client *http.Client, req *http.Request, workflowExecution W
// FIXME // FIXME
// Execute, as we don't really care if env is not set? IDK // Execute, as we don't really care if env is not set? IDK
if action.Environment != environment { //&& action.Environment != "" { if action.Environment != environment { //&& action.Environment != "" {
log.Printf("Bad environment: %s", action.Environment) log.Printf("Bad environment for node: %s. Want %s", action.Environment, environment)
continue continue
} }
@@ -995,6 +1000,7 @@ func main() {
} else { } else {
authorization = os.Getenv("AUTHORIZATION") authorization = os.Getenv("AUTHORIZATION")
executionId = os.Getenv("EXECUTIONID") executionId = os.Getenv("EXECUTIONID")
log.Printf("Running normal execution with auth %s and ID %s", authorization, executionId)
} }
if len(authorization) == 0 { if len(authorization) == 0 {