Skip to content

Commit 8e3a649

Browse files
committed
init
1 parent 5675939 commit 8e3a649

File tree

9 files changed

+158
-0
lines changed

9 files changed

+158
-0
lines changed

consts.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
config_file = "config.json"
2+
github = "Github"
3+
providers = [github]
4+
contexts = ["Cycode: Secrets",
5+
"Cycode: IaC",
6+
"Cycode: Leaks",
7+
"Cycode: CI/CD",
8+
"Cycode: SAST",
9+
"Cycode: Vulnerable Dependencies",
10+
"Cycode: Licenses Compliance", ]

main.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from typing import Dict
2+
3+
from PyInquirer import prompt, Separator
4+
import logging
5+
from consts import providers, contexts, config_file
6+
from menus.menu_base import MenuBase
7+
from menus.release_block_pr_menu import ReleaseBlockPrMenu
8+
9+
release_block_pr_menu = ReleaseBlockPrMenu()
10+
menus = [release_block_pr_menu]
11+
menu_value_to_class: Dict[str, MenuBase] = {menu.get_menu(): menu for menu in menus}
12+
13+
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
14+
logger = logging.getLogger(__name__)
15+
16+
main_menu = [
17+
{
18+
'type': 'list',
19+
'name': 'menu',
20+
'message': 'What do you want to do?',
21+
'choices': [menu for menu in menu_value_to_class.keys()],
22+
23+
},
24+
{
25+
'type': 'input',
26+
'name': 'config_file',
27+
"message": "Please provide a configuration file",
28+
"default": config_file,
29+
'validate': release_block_pr_menu.validate_config_file,
30+
"when": release_block_pr_menu.menu_chosen
31+
},
32+
{
33+
'type': 'list',
34+
'name': 'provider',
35+
"message": "Which provider?",
36+
"choices": providers,
37+
"when": release_block_pr_menu.menu_chosen,
38+
},
39+
{
40+
'type': 'checkbox',
41+
'name': 'contexts',
42+
"message": "Which contexts?",
43+
"choices": [{"name": context} for context in contexts],
44+
"when": release_block_pr_menu.menu_chosen
45+
}
46+
]
47+
48+
if __name__ == '__main__':
49+
answer = prompt(main_menu)
50+
menu = menu_value_to_class.get(answer.get('menu'))
51+
if menu:
52+
menu.handle(answer)
53+
else:
54+
logger.error(f"invalid menu {answer.get('menu')}")

menus/__init__.py

Whitespace-only changes.

menus/menu_base.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from abc import abstractmethod, ABC
2+
3+
4+
class MenuBase(ABC):
5+
def menu_chosen(self, answers):
6+
return answers.get('menu') == self.get_menu()
7+
8+
@abstractmethod
9+
def get_menu(self):
10+
pass
11+
12+
@abstractmethod
13+
def handle(self, answers):
14+
pass

menus/release_block_pr_menu.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
from typing import List, Dict
3+
import pydantic
4+
import logging
5+
from consts import github
6+
from menus.menu_base import MenuBase
7+
from providers.github_handler import GithubHandler
8+
from providers.provider_handler import ProviderHandler
9+
import PyInquirer
10+
from release_block_pr_config import ReleaseBlockPrConfig
11+
12+
logger = logging.getLogger(__name__)
13+
14+
release_block = "Release Blocked PR's"
15+
16+
17+
class ReleaseBlockPrMenu(MenuBase):
18+
handlers: Dict[str, ProviderHandler] = {
19+
github: GithubHandler()
20+
}
21+
22+
def handle(self, answers):
23+
if answers.get("provider") in self.handlers:
24+
handler = self.handlers[answers["provider"]]
25+
repositories_to_unblock: List[ReleaseBlockPrConfig] = pydantic.parse_file_as(List[ReleaseBlockPrConfig],
26+
answers["config_file"])
27+
for tokens_to_repositories in repositories_to_unblock:
28+
for repository in tokens_to_repositories.repositories:
29+
handler.release_branch_protection(tokens_to_repositories.token, repository.organization_name,
30+
repository.organization_name, repository.branch,
31+
answers["contexts"])
32+
else:
33+
logger.error(f"Invalid provider selected: {answers.get('provider')}")
34+
35+
def get_menu(self):
36+
return release_block
37+
38+
@staticmethod
39+
def validate_config_file(config_file):
40+
if not os.path.isfile(config_file):
41+
return "File does not exist"
42+
try:
43+
pydantic.parse_file_as(List[ReleaseBlockPrConfig], config_file)
44+
except Exception as e:
45+
return f"Invalid input, not in the expected format {e}"
46+
return True

providers/__init__.py

Whitespace-only changes.

providers/github_handler.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import logging
2+
from typing import List
3+
4+
from providers.provider_handler import ProviderHandler
5+
6+
logger = logging.getLogger(__name__)
7+
8+
9+
class GithubHandler(ProviderHandler):
10+
def release_branch_protection(self, token, organization_name, repository_name, branch, contexts: List[str]):
11+
logger.info(f"Releasing branch protection on repository {repository_name}")

providers/provider_handler.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from abc import ABC, abstractmethod
2+
from typing import List
3+
4+
5+
class ProviderHandler(ABC):
6+
@abstractmethod
7+
def release_branch_protection(self, token, organization_name, repository_name, branch, contexts: List[str]):
8+
pass

release_block_pr_config.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from typing import List
2+
3+
import pydantic
4+
5+
6+
class RepositoryConfig(pydantic.BaseModel):
7+
repository_name: str
8+
organization_name: str
9+
branch: str
10+
11+
12+
class ReleaseBlockPrConfig(pydantic.BaseModel):
13+
token: str
14+
provider: str
15+
repositories: List[RepositoryConfig]

0 commit comments

Comments
 (0)