Skip to content

Commit

Permalink
Merge pull request #8 from Mubashirshariq/revert-6-feat-1780-runbooks…
Browse files Browse the repository at this point in the history
…-intergation

Revert "Feat 1780 runbooks intergation"
  • Loading branch information
rajesh-jonnalagadda authored Oct 8, 2024
2 parents 51fcfd1 + 1c3f04d commit e86b705
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 265 deletions.
1 change: 0 additions & 1 deletion keep-ui/app/runbooks/runbook-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ function SettingsPage() {
<TextInput
{...register("pathToMdFile")}
placeholder="Enter path to markdown files"
required
/>
</div>
</div>
Expand Down
27 changes: 7 additions & 20 deletions keep-ui/utils/hooks/useRunbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useRunBookTriggers = (values: any, refresh: number) => {
const [synced, setSynced] = useState(false);
const [fileData, setFileData] = useState<any>({});
const [reposData, setRepoData] = useState<any>([]);
const { pathToMdFile, repoName, userName, providerId, domain, runBookTitle } = values || {};
const { pathToMdFile, repoName, userName, providerId, domain } = values || {};
const { data: session } = useSession();
const { installed_providers, providers } = (providersData?.data ||
{}) as ProvidersResponse;
Expand Down Expand Up @@ -67,31 +67,18 @@ export const useRunBookTriggers = (values: any, refresh: number) => {
if (repoName) {
params.append("repo", repoName);
}
if(runBookTitle){
params.append("title", runBookTitle);

}
//TO DO backend runbook records needs to be created.
const response = await fetch(`${baseApiurl}/runbooks/${provider?.type}/${
const response = await fetcher(
`${baseApiurl}/runbooks/${provider?.type}/${
provider?.id
}?${params.toString()}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session?.accessToken}`,
},
});
}/runbook?${params.toString()}`,
session?.accessToken
);

if (!response) {
return setError("Something went wrong. try agian after some time");
}

if(!response.ok) {
return setError("Something went wrong. try agian after some time");

}
const result = await response.json();
setFileData(result);
setFileData(response);
setSynced(false);
} catch (err) {
return setError("Something went wrong. try agian after some time");
Expand Down
1 change: 0 additions & 1 deletion keep/api/models/db/migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from keep.api.models.db.topology import *
from keep.api.models.db.user import *
from keep.api.models.db.workflow import *
from keep.api.models.db.runbook import *

target_metadata = SQLModel.metadata

Expand Down

This file was deleted.

143 changes: 77 additions & 66 deletions keep/api/models/db/runbook.py
Original file line number Diff line number Diff line change
@@ -1,82 +1,93 @@
from uuid import UUID, uuid4
from datetime import datetime
from typing import List, Optional
from uuid import UUID, uuid4

from sqlalchemy import ForeignKey, Column, TEXT, JSON
from sqlmodel import Field, Relationship, SQLModel
from sqlalchemy import Column, ForeignKey, Text
from pydantic import BaseModel
from keep.api.models.db.tenant import Tenant

# Link Model between Runbook and Incident
class RunbookToIncident(SQLModel, table=True):
tenant_id: str = Field(foreign_key="tenant.id")
runbook_id: UUID = Field(foreign_key="runbook.id", primary_key=True)
incident_id: UUID = Field(foreign_key="incident.id", primary_key=True)

# RunbookContent Model
class RunbookContent(SQLModel, table=True):
id: UUID = Field(default_factory=uuid4, primary_key=True)
runbook_id: UUID = Field(
sa_column=Column(ForeignKey("runbook.id", ondelete="CASCADE")) # Foreign key with CASCADE delete
incident_id: UUID = Field(
sa_column=Column(
UUID(binary=False),
ForeignKey("incident.id", ondelete="CASCADE"),
primary_key=True,
)
)
runbook: Optional["Runbook"] = Relationship(back_populates="contents")
content: str = Field(sa_column=Column(Text), nullable=False) # Using SQLAlchemy's Text type
link: str = Field(sa_column=Column(Text), nullable=False) # Using SQLAlchemy's Text type
encoding: Optional[str] = None
created_at: datetime = Field(default_factory=datetime.utcnow) # Timestamp for creation

class Config:
orm_mode = True

# Runbook Model
class Runbook(SQLModel, table=True):
id: UUID = Field(default_factory=uuid4, primary_key=True)
tenant_id: str = Field(
sa_column=Column(ForeignKey("tenant.id", ondelete="CASCADE")) # Foreign key with CASCADE delete
)
repo_id: str # Repository ID
relative_path: str = Field(sa_column=Column(Text), nullable=False) # Path in the repo, must be set
title: str = Field(sa_column=Column(Text), nullable=False) # Title of the runbook, must be set
contents: List["RunbookContent"] = Relationship(back_populates="runbook") # Relationship to RunbookContent
provider_type: str # Type of the provider
provider_id: Optional[str] = None # Optional provider ID
created_at: datetime = Field(default_factory=datetime.utcnow) # Timestamp for creation
tenant_id: str = Field(foreign_key="tenant.id")
tenant: Tenant = Relationship()
repo_id: str = Field(nullable=False) # Github repo id
relative_path: str = Field(nullable=False) # Relative path to the .md file
title: str = Field(nullable=False) # Title of the runbook
link: str = Field(nullable=False) # Link to the .md file

class Config:
orm_mode = True # Enable ORM mode for compatibility with Pydantic models


class RunbookDto(BaseModel, extra="ignore"):
id: UUID
tenant_id: str
repo_id: str
relative_path: str
title: str
contents: List["RunbookContent"] = []
incidents: List["Incident"] = Relationship(
back_populates="runbooks", link_model=RunbookToIncident
)
provider_type: str
provider_id: Optional[str] = None
created_at: datetime = Field(default_factory=datetime.utcnow)

class RunbookContentDto(BaseModel, extra="ignore"):
id: UUID
content: str
link: str
encoding: Optional[str] = None

@classmethod
def from_orm(cls, content: "RunbookContent") -> "RunbookContentDto":
return cls(
id=content.id,
content=content.content,
link=content.link,
encoding=content.encoding
)
class Config:
arbitrary_types_allowed = True


# Incident Model
class Incident(SQLModel, table=True):
id: UUID = Field(default_factory=uuid4, primary_key=True)
tenant_id: str = Field(foreign_key="tenant.id")
tenant: Tenant = Relationship()

class RunbookDtoOut(RunbookDto):
contents: List[RunbookContentDto] = []
@classmethod
def from_orm(
cls, runbook: "Runbook"
) -> "RunbookDtoOut":
return cls(
id=runbook.id,
title=runbook.title,
tenant_id=runbook.tenant_id,
repo_id=runbook.repo_id,
relative_path=runbook.relative_path,
provider_type=runbook.provider_type,
provider_id=runbook.provider_id,
contents=[RunbookContentDto.from_orm(content) for content in runbook.contents]
)
user_generated_name: Optional[str] = None
ai_generated_name: Optional[str] = None

user_summary: Optional[str] = Field(sa_column=Column(TEXT), nullable=True)
generated_summary: Optional[str] = Field(sa_column=Column(TEXT), nullable=True)

assignee: Optional[str] = None
# severity: int = Field(default=IncidentSeverity.CRITICAL.order)

creation_time: datetime = Field(default_factory=datetime.utcnow)

start_time: Optional[datetime] = None
end_time: Optional[datetime] = None
last_seen_time: Optional[datetime] = None

runbooks: List["Runbook"] = Relationship(
back_populates="incidents", link_model=RunbookToIncident
)

is_predicted: bool = Field(default=False)
is_confirmed: bool = Field(default=False)

alerts_count: int = Field(default=0)
affected_services: List = Field(sa_column=Column(JSON), default_factory=list)
sources: List = Field(sa_column=Column(JSON), default_factory=list)

rule_id: Optional[UUID] = Field(
sa_column=Column(
UUID(binary=False),
ForeignKey("rule.id", ondelete="CASCADE"),
nullable=True,
),
)

rule_fingerprint: str = Field(default="", sa_column=Column(TEXT))

def __init__(self, **kwargs):
super().__init__(**kwargs)
if "runbooks" not in kwargs:
self.runbooks = []

class Config:
arbitrary_types_allowed = True
47 changes: 3 additions & 44 deletions keep/api/routes/runbooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@
from keep.identitymanager.identitymanagerfactory import IdentityManagerFactory
from keep.providers.providers_factory import ProvidersFactory
from keep.secretmanager.secretmanagerfactory import SecretManagerFactory
from keep.runbooks.runbooks_service import (
RunbookService
)
from keep.api.models.db.runbook import (
RunbookDtoOut
)


logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -52,8 +45,8 @@ def get_repositories(
return provider.pull_repositories()


@router.get("/{provider_type}/{provider_id}")
def get_runbook(
@router.get("/{provider_type}/{provider_id}/runbook")
def get_repositories(
provider_type: str,
provider_id: str,
authenticated_entity: AuthenticatedEntity = Depends(
Expand All @@ -63,7 +56,6 @@ def get_runbook(
repo: str = Query(None),
branch: str = Query(None),
md_path: str = Query(None),
title: str = Query(None),
):
tenant_id = authenticated_entity.tenant_id
logger.info("Getting runbook", extra={"provider_type": provider_type, "provider_id": provider_id})
Expand All @@ -84,37 +76,4 @@ def get_runbook(
context_manager, provider_id, provider_type, provider_config
)

return provider.pull_runbook(repo=repo, branch=branch, md_path=md_path, title=title)


@router.post(
"/{provider_type}/{provider_id}",
description="Create a new Runbook",
# response_model=RunbookDtoOut,
)
def create_runbook(
provider_type: str,
provider_id: str,
authenticated_entity: AuthenticatedEntity = Depends(
IdentityManagerFactory.get_auth_verifier(["write:runbook"])
),
session: Session = Depends(get_session),
repo: str = Query(None),
branch: str = Query(None),
md_path: str = Query(None),
title: str = Query(None),
):
tenant_id = authenticated_entity.tenant_id
logger.info("Creating Runbook", extra={tenant_id: tenant_id})
context_manager = ContextManager(tenant_id=tenant_id)
secret_manager = SecretManagerFactory.get_secret_manager(context_manager)
provider_config = secret_manager.read_secret(
f"{tenant_id}_{provider_type}_{provider_id}", is_json=True
)
provider = ProvidersFactory.get_provider(
context_manager, provider_id, provider_type, provider_config
)

runbook_dto= provider.pull_runbook(repo=repo, branch=branch, md_path=md_path, title=title)
return RunbookService.create_runbook(session, tenant_id, runbook_dto)

return provider.pull_runbook(repo=repo, branch=branch, md_path=md_path)
2 changes: 1 addition & 1 deletion keep/providers/base/base_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ def pull_topology(self) -> list[TopologyServiceInDto]:


class BaseRunBookProvider(BaseProvider):
def pull_runbook(self, repo=None, branch=None, md_path=None, title=None):
def pull_runbook(self, repo=None, branch=None, md_path=None):
raise NotImplementedError("get_runbook() method not implemented")

def pull_repositories(self):
Expand Down
Loading

0 comments on commit e86b705

Please sign in to comment.