Skip to content

Commit

Permalink
add confluence tool
Browse files Browse the repository at this point in the history
  • Loading branch information
aantn committed Jun 24, 2024
1 parent 0f418b5 commit 050695a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 13 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,32 @@ In particular, note that [vLLM does not yet support function calling](https://gi

</details>

### Enabling Integrations

<details>
<summary>Confluence</summary>
HolmesGPT can read runbooks from Confluence. To give it access, set the following environment variables:

* CONFLUENCE_BASE_URL - e.g. https://robusta-dev-test.atlassian.net
* CONFLUENCE_USER - e.g. [email protected]
* CONFLUENCE_API_KEY - [refer to Atlassian docs on generating API keys](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/)
</details>

<details>
<summary>
Jira, GitHub, OpsGenie, PagerDuty, and AlertManager
</summary>

HolmesGPT can pull tickets/alerts from each of these sources and investigate them.

Refer to `holmes investigate --help` commands for configuration details. E.g. `holmes investigate jira --help`.

See also, <a href="#examples">examples</a>.
</details>

## Other Use Cases

HolmesGPT is usually used for incident response, but it can function as a general-purpose DevOps assistant too. Here are some examples:
HolmesGPT was designed for incident response, but it is a general DevOps assistant too. Here are some examples:

<details>
<summary>Ask Questions About Your Cloud</summary>
Expand Down
35 changes: 23 additions & 12 deletions holmes/core/tools.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os
import re
import shlex
import subprocess
Expand Down Expand Up @@ -115,15 +116,18 @@ def __execute_subprocess(self, cmd) -> str:
return f"Command `{cmd}` failed with return code {e.returncode}\nstdout:\n{e.stdout}\nstderr:\n{e.stderr}"


class ToolsetPrerequisite(BaseModel):
class ToolsetCommandPrerequisite(BaseModel):
command: str # must complete successfully (error code 0) for prereq to be satisfied
expected_output: str = None # optional

class ToolsetEnvironmentPrerequisite(BaseModel):
env: List[str] = [] # optional

class Toolset(BaseModel):
model_config = ConfigDict(extra='forbid')

name: str
prerequisites: List[ToolsetPrerequisite] = []
prerequisites: List[Union[ToolsetCommandPrerequisite, ToolsetEnvironmentPrerequisite]] = []
tools: List[YAMLTool]

_path: PrivateAttr = None
Expand All @@ -148,17 +152,24 @@ def get_disabled_reason(self):

def check_prerequisites(self):
for prereq in self.prerequisites:
try:
result = subprocess.run(prereq.command, shell=True, check=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if prereq.expected_output and prereq.expected_output not in result.stdout:
if isinstance(prereq, ToolsetCommandPrerequisite):
try:
result = subprocess.run(prereq.command, shell=True, check=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if prereq.expected_output and prereq.expected_output not in result.stdout:
self._enabled = False
self._disabled_reason = f"prereq check gave wrong output"
return
except subprocess.CalledProcessError as e:
self._enabled = False
self._disabled_reason = f"prereq check gave wrong output"
return
except subprocess.CalledProcessError as e:
self._enabled = False
self._disabled_reason = f"prereq check failed w/ errorcode {e.returncode}"
logging.debug(f"Toolset {self.name} : Failed to run prereq command {prereq}", exc_info=True)
return
self._disabled_reason = f"prereq check failed with errorcode {e.returncode}"
logging.debug(f"Toolset {self.name} : Failed to run prereq command {prereq}", exc_info=True)
return
elif isinstance(prereq, ToolsetEnvironmentPrerequisite):
for env_var in prereq.env:
if env_var not in os.environ:
self._enabled = False
self._disabled_reason = f"prereq check failed because environment variable {env_var} was not set"
return
self._enabled = True

class YAMLToolExecutor:
Expand Down
13 changes: 13 additions & 0 deletions holmes/plugins/toolsets/confluence.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
toolsets:
- name: "confluence"
prerequisites:
- command: "curl --version"
- env:
- CONFLUENCE_USER
- CONFLUENCE_API_KEY
- CONFLUENCE_BASE_URL

tools:
- name: "fetch_confluence_url"
description: "Fetch a page in confluence"
command: "curl -u ${CONFLUENCE_USER}:${CONFLUENCE_API_KEY} -X GET -H 'Content-Type: application/json' ${CONFLUENCE_BASE_URL}/wiki/rest/api/content/{{ confluence_page_id }}?expand=body.storage"

0 comments on commit 050695a

Please sign in to comment.