Got first working cloud sync trigger fully running
This commit is contained in:
@@ -478,7 +478,7 @@ class AppBase:
|
||||
|
||||
#Actionname: Start_node
|
||||
|
||||
print(f"Actionname: {actionname}")
|
||||
print(f"Actionname: {actionname_lower}")
|
||||
|
||||
# 1. Find the action
|
||||
baseresult = ""
|
||||
@@ -556,14 +556,14 @@ class AppBase:
|
||||
return ""+appendresult, False
|
||||
|
||||
if len(parsersplit) == 1:
|
||||
return baseresult+appendresult, False
|
||||
return str(baseresult)+str(appendresult), False
|
||||
|
||||
baseresult = baseresult.replace("\'", "\"")
|
||||
basejson = {}
|
||||
try:
|
||||
basejson = json.loads(baseresult)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
return baseresult+appendresult, False
|
||||
return str(baseresult)+str(appendresult), False
|
||||
|
||||
data, is_loop = recurse_json(basejson, parsersplit[1:])
|
||||
parseditem = data
|
||||
@@ -577,7 +577,7 @@ class AppBase:
|
||||
print("SET DATA WRAPPER TO %s!" % parsersplit[-1])
|
||||
parseditem = "${%s%s}$" % (parsersplit[-1], json.dumps(data))
|
||||
|
||||
return parseditem+appendresult, is_loop
|
||||
return str(parseditem)+str(appendresult), is_loop
|
||||
|
||||
# Parses parameters sent to it and returns whether it did it successfully with the values found
|
||||
def parse_params(action, fullexecution, parameter):
|
||||
|
||||
@@ -397,10 +397,12 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
|
||||
verifyAddin,
|
||||
)
|
||||
|
||||
if strings.Contains(functionname, "search") {
|
||||
log.Println(data)
|
||||
log.Printf("Queries: %s", queryString)
|
||||
}
|
||||
/*
|
||||
if strings.Contains(functionname, "search") {
|
||||
log.Println(data)
|
||||
log.Printf("Queries: %s", queryString)
|
||||
}
|
||||
*/
|
||||
|
||||
//log.Printf(data)
|
||||
return functionname, data
|
||||
|
||||
+110
-21
@@ -381,16 +381,17 @@ type HookAction struct {
|
||||
}
|
||||
|
||||
type Hook struct {
|
||||
Id string `json:"id" datastore:"id"`
|
||||
Start string `json:"start" datastore:"start"`
|
||||
Info Info `json:"info" datastore:"info"`
|
||||
Actions []HookAction `json:"actions" datastore:"actions,noindex"`
|
||||
Type string `json:"type" datastore:"type"`
|
||||
Owner string `json:"owner" datastore:"owner"`
|
||||
Status string `json:"status" datastore:"status"`
|
||||
Workflows []string `json:"workflows" datastore:"workflows"`
|
||||
Running bool `json:"running" datastore:"running"`
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
Id string `json:"id" datastore:"id"`
|
||||
Start string `json:"start" datastore:"start"`
|
||||
Info Info `json:"info" datastore:"info"`
|
||||
Actions []HookAction `json:"actions" datastore:"actions,noindex"`
|
||||
Type string `json:"type" datastore:"type"`
|
||||
Owner string `json:"owner" datastore:"owner"`
|
||||
Status string `json:"status" datastore:"status"`
|
||||
Workflows []string `json:"workflows" datastore:"workflows"`
|
||||
Running bool `json:"running" datastore:"running"`
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
Environment string `json:"environment" datastore:"environment"`
|
||||
}
|
||||
|
||||
func createFileFromFile(ctx context.Context, bucket *storage.BucketHandle, remotePath, localPath string) error {
|
||||
@@ -3420,6 +3421,10 @@ func handleWebhookCallback(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if hook.Environment == "cloud" {
|
||||
log.Printf("This should trigger in the cloud. Duplicate action allowed onprem.")
|
||||
}
|
||||
|
||||
for _, item := range hook.Workflows {
|
||||
log.Printf("Running webhook for workflow %s with startnode %s", item, hook.Start)
|
||||
workflow := Workflow{
|
||||
@@ -3471,6 +3476,51 @@ func handleWebhookCallback(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func executeCloudAction(action CloudSyncJob, apikey string) error {
|
||||
data, err := json.Marshal(action)
|
||||
if err != nil {
|
||||
log.Printf("Failed cloud webhook action marshalling", err)
|
||||
return err
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
syncUrl := fmt.Sprintf("%s/api/v1/cloud/sync/handle_action", syncUrl)
|
||||
req, err := http.NewRequest(
|
||||
"POST",
|
||||
syncUrl,
|
||||
bytes.NewBuffer(data),
|
||||
)
|
||||
|
||||
req.Header.Add("Authorization", fmt.Sprintf(`Bearer %s`, apikey))
|
||||
newresp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
respBody, err := ioutil.ReadAll(newresp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
Success bool `json:"success"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
log.Printf("Data: %s", string(respBody))
|
||||
responseData := Result{}
|
||||
err = json.Unmarshal(respBody, &responseData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !responseData.Success {
|
||||
return errors.New(fmt.Sprintf("Error from Shuffler: %s", responseData.Reason))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Starts a new webhook
|
||||
func handleNewHook(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
@@ -3493,6 +3543,7 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
|
||||
Name string `json:"name"`
|
||||
Workflow string `json:"workflow"`
|
||||
Start string `json:"start"`
|
||||
Environment string `json:"environment"`
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(request.Body)
|
||||
@@ -3551,6 +3602,37 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Let remote endpoint handle access checks (shuffler.io)
|
||||
currentUrl := fmt.Sprintf("https://shuffler.io/api/v1/hooks/webhook_%s", newId)
|
||||
if requestdata.Environment == "cloud" {
|
||||
log.Printf("[INFO] Should START a cloud webhook for url %s", currentUrl)
|
||||
// https://shuffler.io/v1/hooks/webhook_80184973-3e82-4852-842e-0290f7f34d7c
|
||||
org, err := getOrg(ctx, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed finding org %s: %s", org.Id, err)
|
||||
return
|
||||
}
|
||||
|
||||
action := CloudSyncJob{
|
||||
Type: "webhook",
|
||||
Action: "start",
|
||||
OrgId: org.Id,
|
||||
PrimaryItemId: newId,
|
||||
SecondaryItem: requestdata.Start,
|
||||
ThirdItem: requestdata.Workflow,
|
||||
}
|
||||
|
||||
err = executeCloudAction(action, org.SyncConfig.Apikey)
|
||||
if err != nil {
|
||||
log.Printf("Failed cloud action START execution", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
} else {
|
||||
log.Printf("Successfully set up cloud action schedule")
|
||||
}
|
||||
}
|
||||
|
||||
hook := Hook{
|
||||
Id: newId,
|
||||
Start: requestdata.Start,
|
||||
@@ -3558,7 +3640,7 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
|
||||
Info: Info{
|
||||
Name: requestdata.Name,
|
||||
Description: requestdata.Description,
|
||||
Url: fmt.Sprintf("https://shuffler.io/functions/webhooks/webhook_%s", newId),
|
||||
Url: fmt.Sprintf("https://shuffler.io/api/v1/hooks/webhook_%s", newId),
|
||||
},
|
||||
Type: "webhook",
|
||||
Owner: user.Username,
|
||||
@@ -3571,8 +3653,9 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
|
||||
Field: "",
|
||||
},
|
||||
},
|
||||
Running: false,
|
||||
OrgId: user.ActiveOrg.Id,
|
||||
Running: false,
|
||||
OrgId: user.ActiveOrg.Id,
|
||||
Environment: requestdata.Environment,
|
||||
}
|
||||
|
||||
hook.Status = "running"
|
||||
@@ -3587,10 +3670,10 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
err = increaseStatisticsField(ctx, "total_workflow_triggers", requestdata.Workflow, 1)
|
||||
if err != nil {
|
||||
log.Printf("Failed to increase total workflows: %s", err)
|
||||
log.Printf("[INFO] Failed to increase total workflows: %s", err)
|
||||
}
|
||||
|
||||
log.Println("Set up a new hook")
|
||||
log.Printf("Set up a new hook with ID %s and environment %s", newId, hook.Environment)
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
}
|
||||
@@ -6476,6 +6559,7 @@ func handleAppHotload(location string, forceUpdate bool) error {
|
||||
// Secondary = something to specify what inside workflow to execute
|
||||
// Third = Some data to add to it
|
||||
type CloudSyncJob struct {
|
||||
Id string `json:"id" datastore:"id"`
|
||||
Type string `json:"type" datastore:"type"`
|
||||
Action string `json:"action" datastore:"action"`
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
@@ -6534,12 +6618,12 @@ func handleCloudJob(job CloudSyncJob) error {
|
||||
log.Printf("Handle job with type %s and action %s", job.Type, job.Action)
|
||||
if job.Type == "webhook" {
|
||||
if job.Action == "execute" {
|
||||
log.Printf("Should handle webhook for workflow %s with start node %s and data %s", job.PrimaryItemId, job.SecondaryItem, job.ThirdItem)
|
||||
log.Printf("Should handle webhook for workflow %s with start node %s and data %s", job.PrimaryItemId, job.SecondaryItem)
|
||||
err := handleCloudExecutionOnprem(job.PrimaryItemId, job.SecondaryItem, "webhook", job.ThirdItem)
|
||||
if err != nil {
|
||||
log.Printf("Failed executing workflow from cloud hook: %s", err)
|
||||
} else {
|
||||
log.Printf("Successfully executed workflow from cloud hook: %s", err)
|
||||
log.Printf("Successfully executed workflow from cloud hook!")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6589,7 +6673,6 @@ func remoteOrgJobController(org Org, body []byte) error {
|
||||
Jobs []CloudSyncJob `json:"jobs"`
|
||||
}
|
||||
|
||||
log.Printf("Remote JOB ret: %s", string(body))
|
||||
responseData := retStruct{}
|
||||
err := json.Unmarshal(body, &responseData)
|
||||
if err != nil {
|
||||
@@ -6633,7 +6716,11 @@ func remoteOrgJobController(org Org, body []byte) error {
|
||||
return errors.New("[ERROR] Remote job handler issues.")
|
||||
}
|
||||
|
||||
log.Printf("Got job with reason %s and %d jobs", responseData.Reason, len(responseData.Jobs))
|
||||
if len(responseData.Jobs) > 0 {
|
||||
log.Printf("Remote JOB ret: %s", string(body))
|
||||
log.Printf("Got job with reason %s and %d job(s)", responseData.Reason, len(responseData.Jobs))
|
||||
}
|
||||
|
||||
for _, job := range responseData.Jobs {
|
||||
err = handleCloudJob(job)
|
||||
if err != nil {
|
||||
@@ -6666,6 +6753,8 @@ func remoteOrgJobHandler(org Org, interval int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Data: %s", respBody)
|
||||
|
||||
err = remoteOrgJobController(org, respBody)
|
||||
if err != nil {
|
||||
log.Printf("Failed job controller run: %s", err)
|
||||
@@ -7059,7 +7148,7 @@ func runInit(ctx context.Context) {
|
||||
job := func() {
|
||||
err := remoteOrgJobHandler(org, interval)
|
||||
if err != nil {
|
||||
log.Printf("Failed request with remote org setup: %s", err)
|
||||
log.Printf("Failed request with remote org setup (2): %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7550,7 +7639,7 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
||||
job := func() {
|
||||
err := remoteOrgJobHandler(*org, interval)
|
||||
if err != nil {
|
||||
log.Printf("Failed request with remote org setup: err")
|
||||
log.Printf("Failed request with remote org setup (1): %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,10 @@ type SyncFeatures struct {
|
||||
Schedules SyncData `json:"schedules" datastore:"schedules"`
|
||||
Autocomplete SyncData `json:"autocomplete" datastore:"autocomplete"`
|
||||
Authentication SyncData `json:"authentication" datastore:"authentication"`
|
||||
Webhook SyncData `json:"webhook" datastore:"webhook"`
|
||||
Schedule SyncData `json:"schedule" datastore:"schedule"`
|
||||
UserInput SyncData `json:"user_input" datastore:"user_input"`
|
||||
EmailTrigger SyncData `json:"email_trigger" datastore:"email_trigger"`
|
||||
}
|
||||
|
||||
type SyncData struct {
|
||||
@@ -2657,7 +2661,7 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
|
||||
|
||||
if !startFound {
|
||||
log.Printf("Startnode %s doesn't exist!", workflowExecution.Start)
|
||||
return WorkflowExecution{}, fmt.Sprintf("Workflow action %s doesn't exist in workflow", workflowExecution.Start), errors.New(fmt.Sprintf("Workflow start node %s doesn't exist. Exiting!", workflowExecution.Start))
|
||||
return WorkflowExecution{}, fmt.Sprintf("Workflow action %s doesn't exist in workflow", workflowExecution.Start), errors.New(fmt.Sprintf(`Workflow start node "%s" doesn't exist. Exiting!`, workflowExecution.Start))
|
||||
}
|
||||
|
||||
// Verification for execution environments
|
||||
@@ -4985,7 +4989,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string,
|
||||
}
|
||||
|
||||
if appCounter > 0 {
|
||||
log.Printf("Preloaded %d OpenApi apps in %s!", appCounter, extra)
|
||||
log.Printf("Preloaded %d OpenApi apps in folder %s!", appCounter, extra)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -5662,7 +5666,7 @@ func handleDeleteHook(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id != hook.Owner && user.Role != "admin" {
|
||||
if user.Id != hook.Owner && user.Role != "admin" && user.ActiveOrg.Id != hook.OrgId {
|
||||
log.Printf("Wrong user (%s) for workflow %s", user.Username, hook.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -5685,6 +5689,36 @@ func handleDeleteHook(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Hook: %#v", hook)
|
||||
if hook.Environment == "cloud" {
|
||||
log.Printf("[INFO] Should STOP cloud webhook https://shuffler.io/api/v1/hooks/webhook_%s", hook.Id)
|
||||
org, err := getOrg(ctx, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed finding org %s: %s", org.Id, err)
|
||||
return
|
||||
}
|
||||
|
||||
action := CloudSyncJob{
|
||||
Type: "webhook",
|
||||
Action: "stop",
|
||||
OrgId: org.Id,
|
||||
PrimaryItemId: hook.Id,
|
||||
}
|
||||
|
||||
if len(hook.Workflows) > 0 {
|
||||
action.SecondaryItem = hook.Workflows[0]
|
||||
}
|
||||
|
||||
err = executeCloudAction(action, org.SyncConfig.Apikey)
|
||||
if err != nil {
|
||||
log.Printf("Failed cloud action STOP execution", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
}
|
||||
// https://shuffler.io/v1/hooks/webhook_80184973-3e82-4852-842e-0290f7f34d7c
|
||||
}
|
||||
|
||||
// This is here to force stop and remove the old webhook
|
||||
//image := "webhook"
|
||||
//err = removeWebhookFunction(ctx, fileId)
|
||||
|
||||
+1
-11
@@ -23,14 +23,4 @@
|
||||
#curl -X POST "https://europe-west1-shuffle-241517.cloudfunctions.net/webhook_3ceff795-ce9a-43a2-a2f5-d4401a6e772d" -H "Authorization: Bearer 144308d0-6aab-4d4f-8bb2-75189281ee26" --data 'wut'
|
||||
#curl POST "https://europe-west1-shuffler.cloudfunctions.net/outlooktrigger_be4dbb0a-d396-4544-bc36-e57d1bdb2e40" -H "Authorization: Bearer 144308d0-6aab-4d4f-8bb2-75189281ee26" --data 'wut' -vvv
|
||||
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5001/api/v1/hooks/webhook_e38e0768-191c-42ec-a021-cf17a4339473" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}' -v
|
||||
curl -X POST "http://localhost:5002/api/v1/hooks/webhook_f22b5e54-e55d-48e5-a1d1-f40453513fd3" -H "Content-Type:application/json" --data '{"test": {"hello": "HEYOOOO"}}'
|
||||
|
||||
@@ -30,7 +30,7 @@ import SettingsPage from "./views/SettingsPage";
|
||||
|
||||
import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';
|
||||
|
||||
import AlertTemplate from "react-alert-template-basic";
|
||||
import AlertTemplate from "./components/AlertTemplate";
|
||||
import { positions, Provider } from "react-alert";
|
||||
|
||||
// Production - backend proxy forwarding in nginx
|
||||
@@ -118,7 +118,7 @@ const App = (message, props) => {
|
||||
|
||||
const options = {
|
||||
timeout: 5000,
|
||||
position: positions.BOTTOM_CENTER
|
||||
position: positions.BOTTOM_RIGHT
|
||||
};
|
||||
|
||||
const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ?
|
||||
|
||||
@@ -7,7 +7,7 @@ import CloseIcon from './icons/CloseIcon'
|
||||
const alertStyle = {
|
||||
backgroundColor: '#151515',
|
||||
color: 'white',
|
||||
padding: '10px',
|
||||
padding: 15,
|
||||
textTransform: 'uppercase',
|
||||
borderRadius: '3px',
|
||||
display: 'flex',
|
||||
@@ -15,8 +15,9 @@ const alertStyle = {
|
||||
alignItems: 'center',
|
||||
boxShadow: '0px 2px 2px 2px rgba(0, 0, 0, 0.03)',
|
||||
fontFamily: 'Arial',
|
||||
width: '300px',
|
||||
boxSizing: 'border-box'
|
||||
width: 400,
|
||||
boxSizing: 'border-box',
|
||||
zIndex: 10001,
|
||||
}
|
||||
|
||||
const buttonStyle = {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -884,6 +884,7 @@ const AppCreator = (props) => {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
setAppBuilding(false)
|
||||
setErrorCode(error.toString())
|
||||
alert.error(error.toString())
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user