Skip to content

Commit

Permalink
Added support to multiple Domains for single installation (#81)
Browse files Browse the repository at this point in the history
* Added support to multiple Domains for single installation

* chore: added API test for selection_domain
  • Loading branch information
petruki committed May 29, 2024
1 parent 2c949b7 commit e833435
Show file tree
Hide file tree
Showing 23 changed files with 683 additions and 142 deletions.
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
sonar.projectKey=switcherapi_switcher-slack-app
sonar.projectName=switcher-slack-app
sonar.projectVersion=1.0.7
sonar.projectVersion=2.0.0
sonar.organization=switcherapi
sonar.links.homepage=https://github.com/switcherapi/switcher-slack-app

Expand Down
5 changes: 5 additions & 0 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from store.switcher_store import SwitcherAppInstallationStore
from controller.home import on_change_request_opened, on_home_opened
from controller.change_request import (
on_domain_selected,
on_environment_selected,
on_group_selected,
on_switcher_selected,
Expand Down Expand Up @@ -78,6 +79,10 @@ def app_home_opened(client, event, logger):
def open_change_request(ack, body, client, logger):
on_change_request_opened(ack, body, client, logger)

@app.action("selection_domain")
def selection_domain(ack, body, client, logger):
on_domain_selected(ack, body, client, logger)

# Update Change Request modal with available domain groups
@app.action("selection_environment")
def selection_environment(ack, body, client, logger):
Expand Down
197 changes: 135 additions & 62 deletions src/controller/change_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

from slack_sdk.errors import SlackApiError
from services.switcher_service import SwitcherService
from utils.switcher_util import get_keyval, validate_context_request
from utils.switcher_util import get_environment_keyval, get_keyval, validate_context_request
from utils.slack_payload_util import (
populate_selection,
populate_metadata,
prepare_body,
get_state_value,
get_selected_action
get_selected_action,
get_selected_action_text
)
from payloads.home import APP_HOME
from payloads.change_request import (
Expand All @@ -17,27 +19,71 @@
read_request_metadata
)

def on_domain_selected(ack, body, client, logger):
""" Load environments when domain is selected """

ack()

try:
# Collect args
team_id = body["team"]["id"]
domain_id = get_selected_action(body)
domain_name = get_selected_action_text(body)

envs = SwitcherService().get_environments(team_id, domain_id)

# Populate view and metadata
populate_selection(
body = body["view"],
item = "Environment",
values = get_environment_keyval(envs)
)

populate_metadata(body["view"], {
"domain_id": domain_id,
"domain_name": domain_name
})

# Push changes to view
view_hash = body["view"]["hash"]
view_id = body["view"]["id"]

prepare_body(body)
client.views_update(
view_id = view_id,
hash = view_hash,
view = body["view"]
)

return body["view"]
except Exception as e:
logger.error(f"Error opening change request form: {e}")

def on_environment_selected(ack, body, client, logger):
""" Load groups when environment is selected """

env_selected = get_selected_action(body)
team_id = body["team"]["id"]

ack()

try:
groups = SwitcherService().get_groups(team_id, env_selected)
# Collect args
env_selected = get_selected_action(body)
team_id = body["team"]["id"]
domain_id = read_request_metadata(body["view"])["domain_id"]

groups = SwitcherService().get_groups(team_id, domain_id, env_selected)

# Populate view
populate_selection(
body = body["view"],
item = "Group",
values = get_keyval("name", groups)
)

# Push changes to view
view_hash = body["view"]["hash"]
view_id = body["view"]["id"]

prepare_body(body)

client.views_update(
view_id = view_id,
hash = view_hash,
Expand All @@ -51,16 +97,20 @@ def on_environment_selected(ack, body, client, logger):
def on_group_selected(ack, body, client, logger):
""" Load switchers when group is selected """

env_selected = get_state_value(body["view"], "selection_environment")
group_selected = get_selected_action(body)
team_id = body["team"]["id"]

ack()

try:
# Collect args
env_selected = get_state_value(body["view"], "selection_environment")
group_selected = get_selected_action(body)
team_id = body["team"]["id"]
domain_id = read_request_metadata(body["view"])["domain_id"]

switchers = SwitcherService().get_switchers(
team_id, env_selected, group_selected
team_id, domain_id, env_selected, group_selected
)

# Populate view
populate_selection(
body = body["view"],
item = "Switcher",
Expand All @@ -72,6 +122,7 @@ def on_group_selected(ack, body, client, logger):
{ "name": "Disable", "value": "false" }
])

# Push changes to view
view_hash = body["view"]["hash"]
view_id = body["view"]["id"]

Expand All @@ -90,11 +141,11 @@ def on_switcher_selected(ack, body, client):
""" Updates view's metadata with switcher selection """

ack()

view_hash = body["view"]["hash"]
view_id = body["view"]["id"]

prepare_body(body)

client.views_update(
view_id = view_id,
hash = view_hash,
Expand All @@ -106,26 +157,31 @@ def on_switcher_selected(ack, body, client):
def on_change_request_review(ack, body, client, view, logger):
""" Populate context with selections, validate via Switcher API then publish view for review """

user = body["user"]
team_id = body["team"]["id"]

ack()

environment = get_state_value(view, "selection_environment")
context = {
"environment": environment,
"environment_alias": "Production" if environment == "default" else environment,
"group": get_state_value(view, "selection_group"),
"switcher": get_state_value(view, "selection_switcher"),
"status": get_state_value(view, "selection_status")
}

view = create_request_review(context)
view["private_metadata"] = json.dumps(context)

try:
# Collect args
user = body["user"]
team_id = body["team"]["id"]
environment = get_state_value(view, "selection_environment")

# Create context and validate
context = {
**read_request_metadata(body["view"]),
"environment": environment,
"environment_alias": "Production" if environment == "default" else environment,
"group": get_state_value(view, "selection_group"),
"switcher": get_state_value(view, "selection_switcher"),
"status": get_state_value(view, "selection_status")
}

validate_context_request(context)
result = SwitcherService().validate_ticket(team_id, context)

view = create_request_review(context)
populate_metadata(view, context)

# Publish view and send message
user_message = None

if result == 'VALIDATED':
Expand All @@ -144,10 +200,10 @@ def on_change_request_review(ack, body, client, view, logger):
text = "Change Request Review",
blocks = create_block_message(user_message)
)

return view, user_message
except Exception as e:
logger.error(f"Error request review: {e}")
logger.error(f"Error on change request review: {e}")
client.chat_postMessage(
channel = user["id"],
text = f"There was an error with your request: {e}"
Expand All @@ -156,19 +212,19 @@ def on_change_request_review(ack, body, client, view, logger):
def on_submit(ack, body, client, logger):
""" Create ticket, return to home view then publish approval message """

user = body["user"]
team_id = body["team"]["id"]

ack()

observation = get_state_value(body["view"], "selection_observation")
context = {
**read_request_metadata(body["view"]),
"observations": "" if observation is None else observation,
}

try:
ticket = SwitcherService().create_ticket(team_id, context)
# Collect args
observation = get_state_value(body["view"], "selection_observation")
context = {
**read_request_metadata(body["view"]),
"observations": "" if observation is None else observation,
}

domain_id = context["domain_id"]
user = body["user"]
team_id = body["team"]["id"]

# Return to initial state
client.views_publish(
Expand All @@ -177,8 +233,14 @@ def on_submit(ack, body, client, logger):
view = APP_HOME
)

# Redirect approval
request_message = get_request_message(ticket.get("ticket_id"), context)
# Create ticket and post approval request
ticket = SwitcherService().create_ticket(team_id, context)
ticket_payload = {
"id": ticket.get("ticket_id"),
"domain_id": domain_id,
}

request_message = get_request_message(json.dumps(ticket_payload), context)
client.chat_postMessage(
channel = ticket.get("channel_id"),
text = "The following request has been opened for approval.",
Expand All @@ -204,6 +266,7 @@ def on_change_request_abort(ack, body, client):
""" Return to home view """

ack()

client.views_publish(
response_action = "push",
user_id = body["user"]["id"],
Expand All @@ -212,19 +275,24 @@ def on_change_request_abort(ack, body, client):

def on_request_approved(ack, body, client, logger):
""" Approve ticket through Switcher API and update chat message """

ack()

message_ts = body["message"]["ts"]
team_id = body["team"]["id"]
ticket_id = body["actions"][0]["value"]
channel_id = body["channel"]["id"]
try:
# Collect args
message_ts = body["message"]["ts"]
team_id = body["team"]["id"]
channel_id = body["channel"]["id"]

ack()
ticket_payload = json.loads(body["actions"][0]["value"])
domain_id = ticket_payload["domain_id"]
ticket_id = ticket_payload["id"]

message_blocks = create_block_message(":large_green_square: *Change request approved*")
message_blocks.append(body["message"]["blocks"][2])
message_blocks = create_block_message(":large_green_square: *Change request approved*")
message_blocks.append(body["message"]["blocks"][2])

try:
SwitcherService().approve_request(team_id, ticket_id)
# Approve ticket and update message
SwitcherService().approve_request(team_id, domain_id, ticket_id)
client.chat_update(
channel = channel_id,
text = "Change request approved",
Expand All @@ -244,26 +312,31 @@ def on_request_approved(ack, body, client, logger):

def on_request_denied(ack, body, client, logger):
""" Deny ticket through Switcher API and update chat message """

ack()

message_ts = body["message"]["ts"]
team_id = body["team"]["id"]
ticket_id = body["actions"][0]["value"]
channel_id = body["channel"]["id"]
try:
# Collect args
message_ts = body["message"]["ts"]
team_id = body["team"]["id"]
channel_id = body["channel"]["id"]

ack()
ticket_payload = json.loads(body["actions"][0]["value"])
domain_id = ticket_payload["domain_id"]
ticket_id = ticket_payload["id"]

message_blocks = create_block_message(":large_red_square: *Change request denied*")
message_blocks.append(body["message"]["blocks"][2])
message_blocks = create_block_message(":large_red_square: *Change request denied*")
message_blocks.append(body["message"]["blocks"][2])

try:
SwitcherService().deny_request(team_id, ticket_id)
# Deny ticket and update message
SwitcherService().deny_request(team_id, domain_id, ticket_id)
client.chat_update(
channel = channel_id,
text = "Change request denied",
ts = message_ts,
blocks = message_blocks
)

return message_blocks
except Exception as e:
logger.error(f"Error on denying: {e}")
Expand Down
Loading

0 comments on commit e833435

Please sign in to comment.