Skip to content

Commit

Permalink
Merge pull request #46 from pluralsh/slack-notifs
Browse files Browse the repository at this point in the history
slack notif sync
  • Loading branch information
michaeljguarino authored Apr 23, 2022
2 parents f26127f + 90e364d commit 1f48e67
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 5 deletions.
7 changes: 7 additions & 0 deletions lib/console/pubsub/protocols/webhook.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ defimpl Console.PubSub.Webhook, for: [Console.PubSub.BuildSucceeded, Console.Pub
def deliver(%{item: build}),
do: {:ok, {build, Webhook.ordered()}}
end

defimpl Console.PubSub.Webhook, for: [Console.PubSub.NotificationCreated] do
alias Console.Schema.Webhook

def deliver(%{item: notif}),
do: {:ok, {notif, Webhook.ordered()}}
end
14 changes: 14 additions & 0 deletions lib/console/services/plural.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ defmodule Console.Services.Plural do
alias Console.Schema.{User, Manifest}
alias Console.Services.{Builds}
alias Console.Plural.{Repositories, Users, Recipe, Installation, OIDCProvider, Manifest, Context}
alias Kube.Application
use Nebulex.Caching

@decorate cacheable(cache: Console.Cache, key: {:app, name}, opts: [ttl: @ttl], match: &allow/1)
def application(name) do
Kube.Client.get_application(name)
end

def app_icon(%Application{spec: %Application.Spec{descriptor: %{icons: [%{src: src} | _]}}}),
do: src
def app_icon(_), do: nil

defp allow({:ok, _}), do: true
defp allow(_), do: false

def terraform_file(repository) do
terraform_filename(repository)
Expand Down
45 changes: 40 additions & 5 deletions lib/console/services/webhooks/slack.ex
Original file line number Diff line number Diff line change
@@ -1,23 +1,58 @@
defmodule Console.Webhooks.Formatter.Slack do
use Console.Webhooks.Formatter
alias Console.Schema.Build
alias Console.Schema.{Build, Notification}
alias Console.Services.Plural

@impl Formatter
def format(%Build{status: status, repository: repo, id: id} = build) do
cluster_name = Console.Services.Plural.cluster_name()
cluster_name = Plural.cluster_name()
{:ok, %{attachments: [
%{
color: color(status),
blocks: [
%{type: :section, text: %{
type: "mrkdwn",
section(text: mrkdwn(
text: "[cluster=#{cluster_name}] #{emoji(status)}#{status_modifier(status)} #{repo} using console: <#{build_url(id)}|build logs>\n\n#{build.message}"
}}
))
]
}
]}}
end

def format(%Notification{title: title, description: desc, repository: repo, severity: sev, annotations: anns, labels: labels}) do
app = Plural.application(repo)
cluster_name = Plural.cluster_name()
{:ok, %{
blocks: [
section(
text: mrkdwn(text: "New Notification in cluster: #{cluster_name} for #{repo}\n*#{title}*"),
accessory: image(image_url: Plural.app_icon(app), alt_text: repo)
),
section(text: mrkdwn(text: desc)),
section(fields: [
mrkdwn(text: "*Severity*\n#{sev}"),
mrkdwn(text: "*Annotations*\n#{format_pairs(anns)}"),
mrkdwn(text: "*Labels*\n#{format_pairs(labels)}")
])
]
}}
end

defp section(attrs), do: block(:section, attrs)

defp mrkdwn(attrs), do: block(:mrkdwn, attrs)

defp image(attrs), do: block(:image, attrs)

defp format_pairs(pairs) do
Enum.map(pairs, fn {k, v} -> "*#{k}*: #{v}" end)
|> Enum.join(" ")
end

defp block(type, attrs) do
Map.new(attrs)
|> Map.put(:type, type)
end

defp emoji(:successful), do: ":rocket: "
defp emoji(_), do: ""
end
11 changes: 11 additions & 0 deletions lib/kube/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ defmodule Kube.Client do
|> Kazan.run()
end

def get_application(name) do
ns = Console.namespace(name)
%Kazan.Request{
method: "get",
path: "/apis/app.k8s.io/v1beta1/namespaces/#{ns}/applications/#{name}",
query_params: %{},
response_model: Kube.Application
}
|> Kazan.run()
end

def list_metrics() do
%Kazan.Request{
method: "get",
Expand Down
41 changes: 41 additions & 0 deletions test/console/pubsub/webhook/notifications_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
defmodule Console.Webhook.NotificationTest do
use Console.DataCase, async: false
use Mimic
alias Kube.Application
alias Console.PubSub.Consumers.Webhook
alias Console.PubSub

setup :set_mimic_global

describe "NotificationCreated" do
test "it will send a failed webhook" do
notif = insert(:notification)
%{url: url} = wh = insert(:webhook, type: :slack)

myself = self()
expect(HTTPoison, :post, fn ^url, payload, _ ->
decoded = Jason.decode!(payload)
send myself, {:payload, decoded}
{:ok, decoded}
end)

expect(Kazan, :run, fn _ ->
{:ok, %Application{spec: %Application.Spec{descriptor: %{links: [%{url: "img"}]}}}}
end)

event = %PubSub.NotificationCreated{item: notif}
Webhook.handle_event(event)

assert_receive {:payload, %{"blocks" => [first, second, third]}}

assert refetch(wh).health == :healthy

assert first["text"]
assert first["accessory"]

assert second["text"]

assert third["fields"]
end
end
end

0 comments on commit 1f48e67

Please sign in to comment.