Skip to content

Commit

Permalink
feat: add openshift provider (#1123)
Browse files Browse the repository at this point in the history
  • Loading branch information
pehlicd committed Apr 19, 2024
1 parent 0f9637b commit 681d632
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 1 deletion.
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -190,7 +190,10 @@ Workflow triggers can either be executed manually when an alert is activated or
          
<img width=32 height=32 src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/servicenow-icon.png?raw=true"/>
</p>

<h3 align="center">Container Orchestration platforms</h2>
<p align="center">
<img width=32 height=32 src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/openshift-icon.png?raw=true"/>
</p>

## Getting Started
### Overview
Expand Down
1 change: 1 addition & 0 deletions docs/mint.json
Expand Up @@ -101,6 +101,7 @@
"providers/documentation/mock-provider",
"providers/documentation/mysql-provider",
"providers/documentation/new-relic-provider",
"providers/documentation/openshift-provider",
"providers/documentation/opsgenie-provider",
"providers/documentation/pagerduty-provider",
"providers/documentation/pingdom-provider",
Expand Down
34 changes: 34 additions & 0 deletions docs/providers/documentation/openshift-provider.mdx
@@ -0,0 +1,34 @@
---
title: "Openshift"
description: "Openshift provider to perform rollout restart action on specific resources."
---

## Inputs

- **kind** (required): Kind of the object which will be run rollout restart action run (`deployments`, `statefulset`, `daemonset`).
- **name** (required): Name of the object which will be run rollout restart action run.

## Outputs

- **message**: Message for the action performed.

## Authentication Parameters

This provider offers you to authenticate with Openshift using: api_server, token and insecure.

- **api_server** (required): The api server url of your Openshift cluster.
- **token** (required): The token of your user to authenticate with Openshift.
- **insecure** (optional): If you want to skip the certificate verification, set this to `True`.

## Connecting with the Provider

To connect to Openshift, follow below steps:

1. Log in to your Openshift cluster and create a new service account with required roles.
2. Get the token of the service account.
3. Use the token to authenticate with Openshift.

## Notes

- This provider allows you to interact with Openshift to perform rollout restart actions.

Binary file added keep-ui/public/icons/openshift-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
163 changes: 163 additions & 0 deletions keep/providers/openshift_provider/openshift_provider.py
@@ -0,0 +1,163 @@
import pydantic
import openshift_client as oc
from openshift_client import OpenShiftPythonException, Context
import dataclasses
import traceback

from keep.contextmanager.contextmanager import ContextManager
from keep.providers.base.base_provider import BaseProvider
from keep.providers.models.provider_config import ProviderConfig, ProviderScope


@pydantic.dataclasses.dataclass
class OpenshiftProviderAuthConfig:
"""Openshift authentication configuration."""

api_server: str = dataclasses.field(
default=None,
metadata={
"name": "api_server",
"description": "The openshift api server url",
"required": True,
"sensitive": False,
},
)
token: str = dataclasses.field(
default=None,
metadata={
"name": "token",
"description": "The openshift token",
"required": True,
"sensitive": True,
},
)
insecure: bool = dataclasses.field(
default=False,
metadata={
"name": "insecure",
"description": "Whether to skip tls verification",
"required": False,
"sensitive": False,
},
)


class OpenshiftProvider(BaseProvider):
"""Perform rollout restart actions on Openshift."""

provider_id: str
PROVIDER_DISPLAY_NAME = "Openshift"

PROVIDER_SCOPES = [
ProviderScope(
name="connect_to_openshift",
description="Check if the provided token can connect to the openshift server",
mandatory=True,
alias="Connect to the openshift",
)
]

def __init__(
self, context_manager, provider_id: str, config: ProviderConfig
):
super().__init__(context_manager, provider_id, config)
self.authentication_config = None
self.validate_config()

def dispose(self):
"""Dispose the provider."""
pass

def validate_config(self):
"""
Validates required configuration for Openshift provider.
"""

if self.config.authentication is None:
self.config.authentication = {}
self.authentication_config = OpenshiftProviderAuthConfig(
**self.config.authentication
)

def __get_ocp_client(self):
"""Get the Openshift client."""
oc_context = Context()
oc_context.api_server = self.authentication_config.api_server
oc_context.token = self.authentication_config.token
oc_context.insecure = self.authentication_config.insecure
return oc_context

def validate_scopes(self):
"""
Validates that the provided token has the required scopes to use the provider.
"""
try:
client = self.__get_ocp_client()
with oc.timeout(60 * 30), oc.tracking() as t, client:
if oc.get_config_context() is None:
try:
oc.invoke('login')
except OpenShiftPythonException:
traceback.print_exc()
self.logger.error(f'Tracking:\n{t.get_result().as_json(redact_streams=False)}\n\n')
self.logger.error("Error logging into the API server")
raise Exception("Error logging into the API server")
scopes = {
"connect_to_openshift": True,
}
except Exception as e:
self.logger.exception("Error validating scopes")
scopes = {
"connect_to_openshift": str(e),
}
return scopes

def _notify(self, kind: str, name: str, project_name: str):
"""Rollout restart the specified kind."""
client = self.__get_ocp_client()
client.project_name = project_name
self.logger.info(f"Performing rollout restart for {kind} {name} using openshift provider")
with oc.timeout(60 * 30), oc.tracking() as t, client:
if oc.get_config_context() is None:
self.logger.error(f'Current context not set! Logging into API server: {client.api_server}\n')
try:
oc.invoke('login')
except OpenShiftPythonException:
self.logger.error('error occurred logging into API Server')
traceback.print_exc()
self.logger.error(f'Tracking:\n{t.get_result().as_json(redact_streams=False)}\n\n')
raise Exception("Error logging into the API server")
try:
oc.invoke('rollout', ['restart', kind, name])
except OpenShiftPythonException:
self.logger.error(f"Error restarting {kind} {name}")
raise Exception(f"Error restarting {kind} {name}")

self.logger.info(f"Restarted {kind} {name}")


if __name__ == "__main__":
# Output debug messages
import logging

logging.basicConfig(level=logging.DEBUG, handlers=[logging.StreamHandler()])

# Load environment variables
import os

url = os.environ.get("OPENSHIFT_URL")
token = os.environ.get("OPENSHIFT_TOKEN")
context_manager = ContextManager(
tenant_id="singletenant",
workflow_id="test",
)
config = ProviderConfig(
authentication={
"api_server": url,
"token": token,
}
)
openshift_provider = OpenshiftProvider(context_manager, "openshift-keephq", config)

restart = openshift_provider.notify("deployment", "nginx")
print(restart)

0 comments on commit 681d632

Please sign in to comment.