Skip to content

Commit

Permalink
Merge branch 'master' into kubectl-jq
Browse files Browse the repository at this point in the history
  • Loading branch information
arikalon1 authored Oct 31, 2024
2 parents 367fa7a + 38f1cba commit f264595
Show file tree
Hide file tree
Showing 23 changed files with 2,540 additions and 1,590 deletions.
66 changes: 37 additions & 29 deletions .github/workflows/build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,40 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies and build
# if you change something here, you must also change it in .github/workflows/build-binaries-and-brew.yaml
run: |
python -m pip install --upgrade pip setuptools pyinstaller
curl -sSL https://install.python-poetry.org | python3 - --version 1.4.0
poetry config virtualenvs.create false
poetry install --no-root
sudo apt-get install -y binutils
pyinstaller holmes.py --add-data 'holmes/plugins/runbooks/*:holmes/plugins/runbooks' --add-data 'holmes/plugins/prompts/*:holmes/plugins/prompts' --add-data 'holmes/plugins/toolsets/*:holmes/plugins/toolsets' --hidden-import=tiktoken_ext.openai_public --hidden-import=tiktoken_ext --hiddenimport litellm.llms.tokenizers --collect-data litellm
ls dist
- name: Test the binary
shell: bash
run: |
dist/holmes/holmes version
if [ $? -ne 0 ]; then
echo "Binary test failed"
exit 1
fi
echo "Binary test passed"
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install Python dependencies and build
# if you change something here, you must also change it in .github/workflows/build-binaries-and-brew.yaml
run: |
python -m pip install --upgrade pip setuptools pyinstaller
curl -sSL https://install.python-poetry.org | python3 - --version 1.4.0
poetry config virtualenvs.create false
poetry install --no-root
poetry run python -m playwright install --with-deps chromium
sudo apt-get install -y binutils pandoc
pyinstaller holmes.py --add-data 'holmes/plugins/runbooks/*:holmes/plugins/runbooks' --add-data 'holmes/plugins/prompts/*:holmes/plugins/prompts' --add-data 'holmes/plugins/toolsets/*:holmes/plugins/toolsets' --hidden-import=tiktoken_ext.openai_public --hidden-import=tiktoken_ext --hiddenimport litellm.llms.tokenizers --collect-data litellm
ls dist
- name: Run tests
shell: bash
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
poetry run pytest
- name: Test the binary
shell: bash
run: |
dist/holmes/holmes version
if [ $? -ne 0 ]; then
echo "Binary test failed"
exit 1
fi
echo "Binary test passed"
2 changes: 1 addition & 1 deletion .github/workflows/build-binaries-and-brew.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,4 @@ jobs:
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git commit -am "Update formula for release ${TAG_NAME}"
git push
git push
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,5 @@ cython_debug/
.idea/

.vscode

playwright.png
24 changes: 13 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ ENV PATH="/root/.local/bin/:$PATH"

RUN apt-get update \
&& apt-get install -y \
curl \
git \
apt-transport-https \
gnupg2 \
build-essential \
unzip \
curl \
git \
apt-transport-https \
gnupg2 \
build-essential \
unzip \
&& apt-get purge -y --auto-remove \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app


# Create and activate virtual environment
RUN python -m venv /app/venv --upgrade-deps && \
. /app/venv/bin/activate
Expand All @@ -33,11 +32,11 @@ ARG AMD_URL=https://github.com/Avi-Robusta/kube-lineage/releases/download/v2.1/k
ARG TARGETPLATFORM
# Conditional download based on the platform
RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
curl -L -o kube-lineage $ARM_URL; \
curl -L -o kube-lineage $ARM_URL; \
elif [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
curl -L -o kube-lineage $AMD_URL; \
curl -L -o kube-lineage $AMD_URL; \
else \
echo "Unsupported platform: $TARGETPLATFORM"; exit 1; \
echo "Unsupported platform: $TARGETPLATFORM"; exit 1; \
fi
RUN chmod 777 kube-lineage
RUN ./kube-lineage --version
Expand All @@ -47,7 +46,7 @@ ARG PRIVATE_PACKAGE_REGISTRY="none"
RUN if [ "${PRIVATE_PACKAGE_REGISTRY}" != "none" ]; then \
pip config set global.index-url "${PRIVATE_PACKAGE_REGISTRY}"; \
fi \
&& pip install poetry
&& pip install poetry
ARG POETRY_REQUESTS_TIMEOUT
RUN poetry config virtualenvs.create false
COPY pyproject.toml poetry.lock /app/
Expand Down Expand Up @@ -75,6 +74,7 @@ RUN apt-get update \
jq \
apt-transport-https \
gnupg2 \
pandoc \
&& apt-get purge -y --auto-remove \
&& apt-get install -y --no-install-recommends libexpat1 \
&& rm -rf /var/lib/apt/lists/*
Expand All @@ -101,5 +101,7 @@ RUN git config --global core.symlinks false
# Remove setuptools-65.5.1 installed from python:3.11-slim base image as fix for CVE-2024-6345 until image will be updated
RUN rm -rf /usr/local/lib/python3.11/site-packages/setuptools-65.5.1.dist-info

RUN python -m playwright install --with-deps chromium

ENTRYPOINT ["python", "holmes.py"]
#CMD ["http://docker.for.mac.localhost:9093"]
52 changes: 31 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ The only AI assistant that investigates incidents **like a human does** - by loo

### What Can HolmesGPT Do?
- **Investigate Incidents (AIOps)** from PagerDuty/OpsGenie/Prometheus/Jira/more
- **Bidirectional Integrations** see investigation results inside your existing ticketing/incident management system
- **Bidirectional Integrations** see investigation results inside your existing ticketing/incident management system
- **Automated Triage:** Use HolmesGPT as a first responder. Flag critical alerts and prioritize them for your team to look at
- **Alert Enrichment:** Automatically add context to alerts - like logs and microservice health info - to find root causes faster
- **Alert Enrichment:** Automatically add context to alerts - like logs and microservice health info - to find root causes faster
- **Identify Cloud Problems** by asking HolmesGPT questions about unhealthy infrastructure
- **Runbook Automation in Plain English:** Speed up your response to known issues by investigating according to runbooks you provide

Expand Down Expand Up @@ -92,7 +92,7 @@ By default results are displayed in the CLI. Use `--update` to get the results a
holmes investigate opsgenie --opsgenie-api-key <PLACEHOLDER_APIKEY>
```

By default results are displayed in the CLI . Use `--update --opsgenie-team-integration-key <PLACEHOLDER_TEAM_KEY>` to get the results as a comment in the OpsGenie alerts. Refer to the CLI help for more info.
By default results are displayed in the CLI . Use `--update --opsgenie-team-integration-key <PLACEHOLDER_TEAM_KEY>` to get the results as a comment in the OpsGenie alerts. Refer to the CLI help for more info.

![OpsGenie](./images/opsgenie-holmes-update.png)
</details>
Expand All @@ -105,7 +105,7 @@ By default results are displayed in the CLI . Use `--update --opsgenie-team-inte
holmes investigate pagerduty --pagerduty-api-key <PLACEHOLDER_APIKEY>
```

By default results are displayed in the CLI. Use `--update --pagerduty-user-email <PLACEHOLDER_EMAIL>` to get the results as a comment in the PagerDuty issue. Refer to the CLI help for more info.
By default results are displayed in the CLI. Use `--update --pagerduty-user-email <PLACEHOLDER_EMAIL>` to get the results as a comment in the PagerDuty issue. Refer to the CLI help for more info.

![PagerDuty](./images/pagerduty-holmes-update.png)
</details>
Expand All @@ -124,10 +124,10 @@ Basic plugin to run an investigation on any Kubernetes object, using the shortcu
```yaml
plugins:
holmesgpt:
shortCut: Shift-H
description: Ask HolmesGPT
shortCut: Shift-H
description: Ask HolmesGPT
scopes:
- all
- all
command: bash
background: false
confirm: false
Expand All @@ -151,7 +151,7 @@ plugins:
shortCut: Shift-Q
description: Custom HolmesGPT Ask
scopes:
- all
- all
command: bash
background: false
confirm: false
Expand All @@ -171,7 +171,7 @@ plugins:
# Read the modified line, ignoring lines starting with '#'
user_input=$(grep -v '^#' "$QUESTION_FILE")
echo running: holmes ask "\"$user_input\""
holmes ask "$user_input"
echo "Press 'q' to exit"
while : ; do
Expand Down Expand Up @@ -296,7 +296,7 @@ docker run -it --net=host -v -v ~/.holmes:/root/.holmes -v ~/.aws:/root/.aws -v
<details>
<summary>Run HolmesGPT in your cluster (Helm)</summary>

Most users should install Holmes using the instructions in the [Robusta docs ↗](https://docs.robusta.dev/master/configuration/ai-analysis.html) and NOT the below instructions.
Most users should install Holmes using the instructions in the [Robusta docs ↗](https://docs.robusta.dev/master/configuration/ai-analysis.html) and NOT the below instructions.

By using the ``Robusta`` integration you’ll benefit from an end-to-end integration that integrates with ``Prometheus alerts`` and ``Slack``. Using the below instructions you’ll have to build many of those components yourself.

Expand All @@ -305,7 +305,7 @@ In this mode, all the parameters should be passed to the HolmesGPT deployment, u
We recommend pulling sensitive variables from Kubernetes ``secrets``.

First, you'll need to create your ``holmes-values.yaml`` file, for example:

additionalEnvVars:
- name: MODEL
value: gpt-4o
Expand Down Expand Up @@ -337,7 +337,7 @@ For OpenAI, only the ``model`` and ``api-key`` should be provided
name: my-holmes-secret
key: openAiKey

**Note**: ``gpt-4o`` is optional since it's default model.
**Note**: ``gpt-4o`` is optional since it's default model.

</details>

Expand All @@ -363,11 +363,11 @@ To work with Azure AI, you need to provide the below variables:

<details>
<summary>AWS Bedrock</summary>

enablePostProcessing: true
additionalEnvVars:
- name: MODEL
value: bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
value: bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
- name: AWS_REGION_NAME
value: us-east-1
- name: AWS_ACCESS_KEY_ID
Expand Down Expand Up @@ -402,7 +402,7 @@ HolmesGPT requires an LLM API Key to function. The most common option is OpenAI,

<details>
<summary>OpenAI</summary>

To work with OpenAI’s GPT 3.5 or GPT-4 models you need a paid [OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key).

**Note**: This is different from being a “ChatGPT Plus” subscriber.
Expand Down Expand Up @@ -432,7 +432,7 @@ Set those environment variables and run:
holmes ask "what pods are unhealthy and why?" --model=azure/<DEPLOYMENT_NAME> --api-key=<API_KEY>
```

Refer [LiteLLM Azure docs ↗](https://litellm.vercel.app/docs/providers/azure) for more details.
Refer [LiteLLM Azure docs ↗](https://litellm.vercel.app/docs/providers/azure) for more details.
</details>

<details>
Expand Down Expand Up @@ -463,7 +463,7 @@ aws bedrock list-foundation-models --region=us-east-1

Note that different models are available in different regions. For example, Claude Opus is only available in us-west-2.

Refer to [LiteLLM Bedrock docs ↗](https://litellm.vercel.app/docs/providers/bedrock) for more details.
Refer to [LiteLLM Bedrock docs ↗](https://litellm.vercel.app/docs/providers/bedrock) for more details.
</details>

<details>
Expand All @@ -486,7 +486,7 @@ export OPENAI_API_BASE="http://localhost:11434/v1"
export OPENAI_API_KEY=123
holmes ask "what pods are unhealthy in my cluster?" --model="openai/llama3.1"
```

</details>
<details>
<summary>Using other OpenAI-compatible models</summary>
Expand Down Expand Up @@ -529,6 +529,16 @@ HolmesGPT can pull tickets/alerts from each of these sources and investigate the
Refer to `holmes investigate jira --help` etc for details, or view the <a href="#examples">examples</a>.
</details>


<details>
<summary>
Fetching runbooks through URLs
</summary>

HolmesGPT can consult webpages containing runbooks or other relevant information.
HolmesGPT uses playwright to scrape webpages and requires playwright to be installed and working through `playwright install`.
</details>

## Other Use Cases

HolmesGPT was designed for incident response, but it is a general DevOps assistant too. Here are some examples:
Expand Down Expand Up @@ -698,7 +708,7 @@ opsgenie-query: "..."

1. **opsgenie_api_key**: The OpsGenie API key. Get it from Settings > API key management > Add new API key
2. **opsgenie-team-integration-key**: OpsGenie Team Integration key for writing back results. (NOT a normal API Key.) Get it from Teams > YourTeamName > Integrations > Add Integration > API Key. Don't forget to turn on the integration and add the Team as Responders to the alert.
3. **opsgenie-query**: E.g. 'message: Foo' (see https://support.atlassian.com/opsgenie/docs/search-queries-for-alerts/)
3. **opsgenie-query**: E.g. 'message: Foo' (see https://support.atlassian.com/opsgenie/docs/search-queries-for-alerts/)
</details>


Expand Down Expand Up @@ -786,7 +796,7 @@ To contribute to HolmesGPT, first follow the <a href="#installation"><strong>Ins
<details>
<summary>Adding new runbooks</summary>

You can contribute knowledge on solving common alerts and HolmesGPT will use this knowledge to solve related issues. To do so, add a new file to [./holmes/plugins/runbooks](holmes/plugins/runbooks) - or edit an existing runbooks file in that same directory.
You can contribute knowledge on solving common alerts and HolmesGPT will use this knowledge to solve related issues. To do so, add a new file to [./holmes/plugins/runbooks](holmes/plugins/runbooks) - or edit an existing runbooks file in that same directory.

Note: if you prefer to keep your runbooks private, you can store them locally and pass them to HolmesGPT with the `-r` flag. However, if your runbooks relate to common problems that others may encounter, please consider opening a PR and making HolmesGPT better for everyone!

Expand All @@ -795,7 +805,7 @@ Note: if you prefer to keep your runbooks private, you can store them locally an
<details>
<summary>Adding new toolsets</summary>

You can add define new tools in YAML and HolmesGPT will use those tools in it's investigation. To do so, add a new file to [./holmes/plugins/toolsets](holmes/plugins/toolsets) - or edit an existing toolsets file in that same directory.
You can add define new tools in YAML and HolmesGPT will use those tools in it's investigation. To do so, add a new file to [./holmes/plugins/toolsets](holmes/plugins/toolsets) - or edit an existing toolsets file in that same directory.

Note: if you prefer to keep your tools private, you can store them locally and pass them to HolmesGPT with the `-t` flag. However, please consider contributing your toolsets! At least one other community member will probably find them useful!

Expand Down
16 changes: 8 additions & 8 deletions holmes/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from holmes.core.runbooks import RunbookManager
from holmes.core.tool_calling_llm import (IssueInvestigator, ToolCallingLLM,
YAMLToolExecutor)
ToolExecutor)
from holmes.core.tools import ToolsetPattern, get_matching_toolsets
from holmes.plugins.destinations.slack import SlackDestination
from holmes.plugins.runbooks import (load_builtin_runbooks,
Expand Down Expand Up @@ -65,7 +65,7 @@ class Config(RobustaBaseConfig):
opsgenie_api_key: Optional[SecretStr] = None
opsgenie_team_integration_key: Optional[SecretStr] = None
opsgenie_query: Optional[str] = None

custom_runbooks: List[FilePath] = []
custom_toolsets: List[FilePath] = []

Expand Down Expand Up @@ -101,7 +101,7 @@ def load_from_env(cls):

def _create_tool_executor(
self, console: Console, allowed_toolsets: ToolsetPattern
) -> YAMLToolExecutor:
) -> ToolExecutor:
all_toolsets = load_builtin_toolsets()
for ts_path in self.custom_toolsets:
all_toolsets.extend(load_toolsets_from_file(ts_path))
Expand Down Expand Up @@ -138,7 +138,7 @@ def _create_tool_executor(
logging.debug(
f"Starting AI session with tools: {[t.name for t in enabled_tools]}"
)
return YAMLToolExecutor(enabled_toolsets)
return ToolExecutor(enabled_toolsets)

def create_toolcalling_llm(
self, console: Console, allowed_toolsets: ToolsetPattern
Expand Down Expand Up @@ -207,21 +207,21 @@ def create_github_source(self) -> GitHubSource:
repository=self.github_repository,
query=self.github_query,
)

def create_pagerduty_source(self) -> OpsGenieSource:
if self.pagerduty_api_key is None:
raise ValueError("--pagerduty-api-key must be specified")

return PagerDutySource(
api_key=self.pagerduty_api_key.get_secret_value(),
user_email=self.pagerduty_user_email,
incident_key=self.pagerduty_incident_key,
)

def create_opsgenie_source(self) -> OpsGenieSource:
if self.opsgenie_api_key is None:
raise ValueError("--opsgenie-api-key must be specified")

return OpsGenieSource(
api_key=self.opsgenie_api_key.get_secret_value(),
query=self.opsgenie_query,
Expand Down
Loading

0 comments on commit f264595

Please sign in to comment.