Skip to content

Commit

Permalink
support to get tenant info from multiple cluster
Browse files Browse the repository at this point in the history
Signed-off-by: wanjunlei <wanjunlei@kubesphere.io>
  • Loading branch information
wanjunlei committed May 13, 2024
1 parent 0c0535a commit e212470
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 98 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/push-sidecar-image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#
# Copyright 2022 The Notification-Manager Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

name: WorkFlow for Building sidecar image

on:
push:
branches:
- 'master'
paths:
- '.github/workflows/push-sidecar-image.yaml'
- 'sidecar/kubesphere/4.0.0/backend.go'
- - 'sidecar/kubesphere/4.0.0/Dockerfile'
- 'sidecar/kubesphere/4.0.0/main.go'
- 'sidecar/kubesphere/4.0.0//Makefile'
- 'sidecar/kubesphere/4.0.0/go.sum'
- 'sidecar/kubesphere/4.0.0/go.mod'

env:
REPO_OP: 'kubesphere'

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
name: Build Operator Image
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.20.x

- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}

- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@v1
with:
image: tonistiigi/binfmt:latest
platforms: all

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1

- name: Build and Push image
run: |
cd sidecar/kubesphere/4.0.0
make
2 changes: 1 addition & 1 deletion config/samples/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data:
{{ define "nm.default.message.cn" }}{{ if ne (len .Status) 0 }}[{{ .Status | translate }}] {{ end }}{{ .MessageCN }}{{ end }}
{{ define "nm.default.subject" }}{{ if eq (len .Alerts) 1 }}{{ range .Alerts }}{{ template "nm.default.message" . }}{{ end }}{{ else }}{{ .Alerts | len }} {{ if ne (len .Status) 0 }}{{ .Status }} {{ end }}alerts{{ if gt (len .GroupLabels.SortedPairs) 0 }} for {{ range .GroupLabels.SortedPairs }}{{ .Name | translate }}={{ .Value }} {{ end }}{{ end }}{{ end }}{{ end }}
{{ define "nm.subject" }}{{ .Alerts | len }} {{ if ne (len .Status) 0 }}{{ .Status }} {{ end }}alerts{{ if gt (len .CommonLabels.SortedPairs) 0 }} for {{ range .CommonLabels.SortedPairs }}{{ .Name | translate }}={{ .Value }} {{ end }}{{ end }}{{ end }}
{{ define "nm.subject" }}{{ $numAlerts := len .Alerts }}{{ if eq $numAlerts 0 }}Show nothing{{ else if eq $numAlerts 1 }}{{ range .Alerts }}{{ $alertTitle := "" }}{{ $alertType := .Labels.alerttype }}{{ $alertName := .Labels.alertname }}{{ $cluster := .Labels.cluster }}{{ $node := .Labels.node }}{{ $pod := .Labels.pod }}{{ $namespace := .Labels.namespace }}{{ if eq $alertType "metric" }}{{ $alertTitle = "[Metrics Alert]" }}{{ else if eq $alertType "auditing" }}{{ $alertTitle = "[Audit Alert]" }}{{ else if eq $alertType "event" }}{{ $alertTitle = "[Event Alert]" }}{{ else }}{{ $alertTitle = "[Unknown Alert]" }}{{ end }}{{ $output := printf "%s" $alertTitle }}{{ if $alertName }}{{ $output = printf "%s alertname=%s" $output $alertName }}{{ end }}{{ if $cluster }}{{ $output = printf "%s | cluster=%s" $output $cluster }}{{ end }}{{ if $namespace }}{{ $output = printf "%s | namespace=%s" $output $namespace }}{{ end }}{{ if $pod }}{{ $output = printf "%s | pod=%s" $output $pod }}{{ if $node }}{{ $output = printf "%s/node=%s" $output $node }}{{ end }}{{ else }}{{ if $node }}{{ $output = printf "%s | node=%s" $output $node }}{{ end }}{{ end }}{{ $output }}{{ end }}{{ else }}{{ $alertTitle := "[Aggregation" }}{{ $alertType := index .GroupLabels "alerttype" }}{{ $alertName := index .GroupLabels "alertname" }}{{ $cluster := index .GroupLabels "cluster" }}{{ $namespace := index .GroupLabels "namespace" }}{{ if eq $alertType "metric" }}{{ $alertTitle = printf "%s Metrics Alert]" $alertTitle }}{{ else if eq $alertType "auditing" }}{{ $alertTitle = printf "%s Audit Alert]" $alertTitle }}{{ else if eq $alertType "event" }}{{ $alertTitle = printf "%s Event Alert]" $alertTitle }}{{ else }}{{ $alertTitle = printf "%s Alert]" $alertTitle }}{{ end }}{{ $output := printf "%s" $alertTitle }}{{ if $alertName }}{{ $output = printf "%s alertname=%s" $output $alertName }}{{ end }}{{ if $cluster }}{{ $output = printf "%s | cluster=%s" $output $cluster }}{{ end }}{{ if $namespace }}{{ $output = printf "%s | namespace=%s" $output $namespace }}{{ end }}{{ $output }}{{ end }}{{ end }}
{{ define "nm.default.text" }}{{ range .Alerts }}{{ template "nm.default.message" . }}
{{ range .Labels.SortedPairs }} {{ .Name | translate }}: {{ .Value }}
Expand Down
1 change: 1 addition & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
DiscordContent = "content"
DiscordEmbed = "embed"

Cluster = "cluster"
Namespace = "namespace"

AlertFiring = "firing"
Expand Down
11 changes: 6 additions & 5 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ func (c *Controller) receiverChanged(t *task) {
_ = level.Info(c.logger).Log("msg", "Receiver changed", "op", t.op, "name", receiver.Name)
}

func (c *Controller) tenantIDFromNs(namespace string) ([]string, error) {
func (c *Controller) tenantIDFromNs(cluster, namespace string) ([]string, error) {
tenantIDs := make([]string, 0)
// Use namespace as TenantID directly if tenantSidecar not provided.
if !c.tenantSidecar {
Expand All @@ -514,7 +514,8 @@ func (c *Controller) tenantIDFromNs(namespace string) ([]string, error) {
}

p := make(map[string]string)
p["namespace"] = namespace
p[constants.Cluster] = cluster
p[constants.Namespace] = namespace
u, err := utils.UrlWithParameters(tenantSidecarURL, p)
if err != nil {
return nil, err
Expand All @@ -536,7 +537,7 @@ func (c *Controller) tenantIDFromNs(namespace string) ([]string, error) {
return nil, err
}

_ = level.Debug(c.logger).Log("msg", "get tenants from namespace", "namespace", namespace, "tenant", utils.ArrayToString(res, ","))
_ = level.Debug(c.logger).Log("msg", "get tenants from namespace", "cluster", cluster, "namespace", namespace, "tenant", utils.ArrayToString(res, ","))

return res, nil
}
Expand Down Expand Up @@ -580,13 +581,13 @@ func getMatchedConfig(r internal.Receiver, configs map[string]map[string]interna
}
}

func (c *Controller) RcvsFromNs(namespace *string) []internal.Receiver {
func (c *Controller) RcvsFromNs(cluster string, namespace *string) []internal.Receiver {

// Global receiver should receive all notifications.
tenants := []string{globalTenantID}
if namespace != nil && len(*namespace) > 0 {
// Get all tenants which need to receive the notifications in this namespace.
tenantIDs, err := c.tenantIDFromNs(*namespace)
tenantIDs, err := c.tenantIDFromNs(cluster, *namespace)
if err != nil {
_ = level.Error(c.logger).Log("msg", "get tenantID error", "err", err, "namespace", *namespace)
} else {
Expand Down
17 changes: 12 additions & 5 deletions pkg/route/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package route

import (
"context"
"fmt"
"strings"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
Expand Down Expand Up @@ -51,25 +53,30 @@ func (s *routeStage) Exec(ctx context.Context, l log.Logger, data interface{}) (
return ctx, nil, err
}

// Grouping alerts by namespace
// Grouping alerts by cluster and namespace
alertMap := make(map[string][]*template.Alert)
for _, alert := range input {
ns := alert.Labels[constants.Namespace]
as := alertMap[ns]
cluster := alert.Labels[constants.Cluster]
key := fmt.Sprintf("%s|%s", cluster, ns)
as := alertMap[key]
as = append(as, alert)
alertMap[ns] = as
alertMap[key] = as
}

m := make(map[string]*packet)
routePolicy := s.notifierCtl.GetRoutePolicy()
for ns, alerts := range alertMap {
for key, alerts := range alertMap {
flag := false
pair := strings.Split(key, "|")
cluster := pair[0]
ns := pair[1]
var tenantRcvs []internal.Receiver
for _, alert := range alerts {
rcvs := s.rcvsFromRouter(alert, routers)
if routePolicy == RouterPolicyAll || (routePolicy == RouterFirst && len(rcvs) == 0) {
if len(tenantRcvs) == 0 && !flag {
tenantRcvs = s.notifierCtl.RcvsFromNs(&ns)
tenantRcvs = s.notifierCtl.RcvsFromNs(cluster, &ns)
flag = true
}
rcvs = append(rcvs, tenantRcvs...)
Expand Down
2 changes: 1 addition & 1 deletion sidecar/kubesphere/4.0.0/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.

IMG ?= kubesphere/notification-tenant-sidecar:v4.0.0
IMG ?= kubesphere/notification-tenant-sidecar:v4.0.1
AMD64 ?= -amd64

all: docker-build
Expand Down

0 comments on commit e212470

Please sign in to comment.