diff --git a/examples/workflows/bash_example.yml b/examples/workflows/bash_example.yml new file mode 100644 index 000000000..4b5518ef9 --- /dev/null +++ b/examples/workflows/bash_example.yml @@ -0,0 +1,29 @@ +workflow: + id: Resend-Python-service + description: Python Resend Mail + triggers: + - type: manual + owners: [] + services: [] + steps: + - name: run-script + provider: + config: '{{ providers.default-bash }}' + type: bash + with: + command: python3 test.py + timeout: 5 + actions: + - condition: + - assert: '{{ steps.run-script.results.return_code }} == 0' + name: assert-condition + type: assert + name: trigger-resend + provider: + type: resend + config: "{{ providers.resend-test }}" + with: + _from: "onboarding@resend.dev" + to: "youremail.dev@gmail.com" + subject: "Python test is up!" + html:

Python test is up!

diff --git a/keep-ui/app/providers/provider-form.tsx b/keep-ui/app/providers/provider-form.tsx index a8f12b9d0..64cc4e36b 100644 --- a/keep-ui/app/providers/provider-form.tsx +++ b/keep-ui/app/providers/provider-form.tsx @@ -34,6 +34,7 @@ import { ProviderSemiAutomated } from "./provider-semi-automated"; import ProviderFormScopes from "./provider-form-scopes"; import Link from "next/link"; import cookieCutter from "@boiseitguru/cookie-cutter"; +import { useSearchParams } from "next/navigation"; type ProviderFormProps = { provider: Provider; @@ -92,6 +93,7 @@ const ProviderForm = ({ isLocalhost, }: ProviderFormProps) => { console.log("Loading the ProviderForm component"); + const searchParams = useSearchParams(); const initialData = { provider_id: provider.id, // Include the provider ID in formValues ...formData, @@ -106,7 +108,6 @@ const ProviderForm = ({ const [inputErrors, setInputErrors] = useState<{ [key: string]: boolean }>( {} ); - const [isModalOpen, setIsModalOpen] = useState(false); // Related to scopes const [providerValidatedScopes, setProviderValidatedScopes] = useState<{ [key: string]: boolean | string; @@ -132,8 +133,18 @@ const ProviderForm = ({ const verifier = generateRandomString(); cookieCutter.set("verifier", verifier); const verifierChallenge = base64urlencode(await sha256(verifier)); + + let oauth2Url = provider.oauth2_url; + if (searchParams?.get("domain")) { + // TODO: this is a hack for Datadog OAuth2 since it can be initated from different domains + oauth2Url = oauth2Url?.replace( + "datadoghq.com", + searchParams.get("domain") + ); + } + window.location.assign( - `${provider.oauth2_url}&redirect_uri=${window.location.origin}/providers/oauth2/${provider.type}&code_challenge=${verifierChallenge}&code_challenge_method=S256` + `${oauth2Url}&redirect_uri=${window.location.origin}/providers/oauth2/${provider.type}&code_challenge=${verifierChallenge}&code_challenge_method=S256` ); } diff --git a/keep/providers/bash_provider/bash_provider.py b/keep/providers/bash_provider/bash_provider.py index 63bde85c9..cbf418419 100644 --- a/keep/providers/bash_provider/bash_provider.py +++ b/keep/providers/bash_provider/bash_provider.py @@ -25,6 +25,7 @@ def _query(self, **kwargs): Returns: _type_: _description_ """ + timeout = kwargs.get("timeout", 60) command = kwargs.get("command", "") parsed_command = self.io_handler.parse(command) # parse by pipes @@ -57,14 +58,31 @@ def _query(self, **kwargs): processes.append(process) # Get the final output - stdout, stderr = processes[-1].communicate() - return_code = processes[-1].returncode - # stdout and stderr are strings or None - if stdout: - stdout = stdout.decode() - - if stderr: - stderr = stderr.decode() + try: + stdout, stderr = processes[-1].communicate(timeout=timeout) + return_code = processes[-1].returncode + # stdout and stderr are strings or None + if stdout or stdout == b"": + stdout = stdout.decode() + + if stderr or stderr == b"": + stderr = stderr.decode() + except subprocess.TimeoutExpired: + # use check_output to get the output of the last process + # this is some MacOS bug, where communicate() doesn't work and raise TimeoutExpired (idk why but it works on Linux) + try: + self.logger.warning("TimeoutExpired, using check_output - MacOS bug?") + stdout = subprocess.check_output( + cmd, stderr=subprocess.STDOUT, timeout=timeout, shell=True + ).decode() + stderr = None + return_code = 0 + self.logger.warning("check_output worked") + # todo: fix that + except Exception as e: + stdout = None + stderr = e.args[1].decode() + return_code = e.args[0] return { "stdout": str(stdout),