-
Notifications
You must be signed in to change notification settings - Fork 785
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add openshift provider (#1123)
- Loading branch information
Showing
6 changed files
with
202 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
|
Loading
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
163
keep/providers/openshift_provider/openshift_provider.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |