diff --git a/.github/tvarit/conf/prod/lightsail.sh b/.github/tvarit/conf/prod/lightsail.sh new file mode 100644 index 0000000000..9a05653ccc --- /dev/null +++ b/.github/tvarit/conf/prod/lightsail.sh @@ -0,0 +1,27 @@ +echo "executing user data" +sudo su +apt update +apt install docker.io -y + +cd /home/ubuntu +curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" +apt install unzip -y +unzip awscliv2.zip +./aws/install +sleep 300 +rm -rf awscliv2.zip + +#with only ECR pull access. TODO: update +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_REGION="eu-central-1" + +aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID +aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY + +docker login -u AWS -p $(aws ecr get-login-password --region eu-central-1) 250373516626.dkr.ecr.eu-central-1.amazonaws.com +docker pull 250373516626.dkr.ecr.eu-central-1.amazonaws.com/lightsailinstance:latest +#docker run -d -p 3000:3000 grafana/grafana +docker run -d -p 80:3000 250373516626.dkr.ecr.eu-central-1.amazonaws.com/lightsailinstance:latest +docker images >> test.txt +echo "user data executed" diff --git a/.github/tvarit/deploy_to_dev_16.sh b/.github/tvarit/deploy_to_dev_16.sh new file mode 100644 index 0000000000..a569896be4 --- /dev/null +++ b/.github/tvarit/deploy_to_dev_16.sh @@ -0,0 +1,193 @@ +#!/usr/bin/env bash +set -e + +PREFIX=$1 +if [ -z "${PREFIX}" ]; then + echo "Usage .github/tvarit/deploy_to_dev_sk.sh " + exit 1 +fi + +validate_lightsail_instance() { + local instance_name="$1" + aws lightsail get-instance --instance-name "$instance_name" >/dev/null 2>&1 + return $? +} + +delete_lightsail_instance() { + local instance_name="$1" + aws lightsail delete-instance --instance-name $instance_name +} + +add_instance_to_load_balancer() { + local instance_name="$1" + local load_balancer_name="$2" + aws lightsail attach-instances-to-load-balancer --load-balancer-name "$load_balancer_name" --instance-names "$instance_name" +} + +check_load_balancer_existence() { + local load_balancer_name="$1" + aws lightsail get-load-balancer --load-balancer-name "$load_balancer_name" >/dev/null 2>&1 + return $? +} + +create_load_balancer() { + local load_balancer_name="$1" + local instance_port="$2" + aws lightsail create-load-balancer --load-balancer-name "$load_balancer_name" --instance-port "$instance_port" +} + +wait_for_instance_ready() { + local instance_name="$1" + end=$((SECONDS+600)) + while [ $SECONDS -lt $end ]; do + instance_state=$(aws lightsail get-instance --instance-name "$instance_name" --query 'instance.state.name' --output text) + if [[ "$instance_state" == "running" ]]; then + return 0 + fi + sleep 10 + done + echo "Instance did not become ready in 10 minutes." + exit 1 +} + +wait_for_lb_instance_healthy() { + local load_balancer_name="$1" + local instance_name="$2" + end=$((SECONDS+600)) + while [ $SECONDS -lt $end ]; do + instance_health=$(aws lightsail get-load-balancer --load-balancer-name "$load_balancer_name" --query "loadBalancer.instanceHealth[?instanceName=='$instance_name'].status" --output text) + if [[ "$instance_health" == "healthy" ]]; then + return 0 + fi + sleep 10 + done + echo "Instance did not become healthy on the load balancer in 10 minutes." + exit 1 +} + +echo "Creating Test database..." +aws lightsail create-relational-database \ + --relational-database-name ${PREFIX}-grafana-db \ + --availability-zone ${AWS_DEFAULT_REGION}a \ + --relational-database-blueprint-id mysql_8_0 \ + --relational-database-bundle-id micro_1_0 \ + --preferred-backup-window 00:00-00:30 \ + --preferred-maintenance-window Sun:01:00-Sun:01:30 \ + --master-database-name grafana \ + --master-username grafana \ + --no-publicly-accessible || : + +echo "Waiting for database to be available..." +for run in {1..60}; do + state=$(aws lightsail get-relational-database --relational-database-name ${PREFIX}-grafana-db --output text --query 'relationalDatabase.state') + if [ "${state}" == "available" ]; then + break + fi + echo "Waiting for database to be available..." + sleep 5 +done + +if [ "${state}" != "available" ]; then + echo "Database not created in 5 mins" + exit 1 +fi + +DB_ENDPOINT=$(aws lightsail get-relational-database --relational-database-name ${PREFIX}-grafana-db --output text --query 'relationalDatabase.masterEndpoint.address') +DB_PASSWORD=$(aws lightsail get-relational-database-master-user-password --relational-database-name ${PREFIX}-grafana-db --output text --query masterUserPassword) +SIGNING_SECRET=$(aws secretsmanager get-secret-value --secret-id grafana-signing-secret --output text --query SecretString) + +#AWS-016 +AWS_ACCESS_KEY=$(aws secretsmanager get-secret-value --secret-id /credentials/grafana-user/access-key --output text --query SecretString) +AWS_SECRET_KEY=$(aws secretsmanager get-secret-value --secret-id /credentials/grafana-user/secret-key --output text --query SecretString) + +echo "Building docker image..." +docker build --tag grafana/grafana:latest . + +cd .github/tvarit/conf/prod/ +echo "Downloading plugins..." +rm -rf plugins +aws s3 sync s3://com.tvarit.grafana.artifacts/grafana-test-plugins plugins +find plugins/ -type f -name *.tar.gz -exec bash -c 'cd $(dirname $1) && tar -xf $(basename $1) && rm $(basename $1); cd -' bash {} \; + +echo "Finalising docker image..." +cp grafana.ini.template grafana.ini +sed -i "s##${PREFIX}.tvarit.com#g" grafana.ini +sed -i "s##https://${PREFIX}.tvarit.com/#g" grafana.ini +sed -i "s##${SIGNING_SECRET}#g" grafana.ini +sed -i "s##${DB_ENDPOINT}#g" grafana.ini +sed -i "s##$(echo ${DB_PASSWORD} | sed 's/#/\\#/g' | sed 's/&/\\&/g')#g" grafana.ini +sed -i "s##${OAUTH_CLIENT_ID}#g" grafana.ini +sed -i "s##${OAUTH_CLIENT_SECRET}#g" grafana.ini +sed -i "s##${SMTP_HOST}#g" grafana.ini +sed -i "s##${SMTP_USER}#g" grafana.ini +sed -i "s##${SMTP_PASSWORD}#g" grafana.ini +sed -i "s##[BETA] Tvarit AI Platform#g" grafana.ini + +cp cloudwatch.json.template cloudwatch.json +sed -i "s##${PREFIX}.tvarit.com#g" cloudwatch.json + +cp Dockerfile.template Dockerfile +sed -i "s##grafana/grafana:latest#g" Dockerfile +sed -i "s##${AWS_ACCESS_KEY}#g" Dockerfile +sed -i "s##${AWS_SECRET_KEY}#g" Dockerfile +sed -i "s##${AWS_DEFAULT_REGION}#g" Dockerfile +docker build --tag grafana/grafana:latest . + +#push Docker image to ECR +echo "push docker image to ECR........." +aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 250373516626.dkr.ecr.eu-central-1.amazonaws.com +docker tag grafana/grafana:latest 250373516626.dkr.ecr.eu-central-1.amazonaws.com/lightsailinstance:latest +docker push 250373516626.dkr.ecr.eu-central-1.amazonaws.com/lightsailinstance:latest + + +# Fetch the name of the only Lightsail instance +instance_name=$(aws lightsail get-instances --query "instances[0].name" --output text) + +if [ -z "$instance_name" ]; then + echo "No Lightsail instances found." + exit 1 +fi + +timestamp=$(date +%Y%m%d%H%M%S) + +new_instance_name="grafana-${PREFIX}-$timestamp" + +# Check if previous instance exists +return_value_instance=$(validate_lightsail_instance $instance_name) +if [ $? -eq 0 ]; then + previous_instance_exists=true +else + previous_instance_exists=false +fi + +echo "Creating lightsail instance!!!!!!" +cp lightsail.sh userdata.sh +sed -i "s##${AWS_ACCESS_KEY_ID_016}#g" userdata.sh +sed -i "s##${AWS_SECRET_KEY_ID_016}#g" userdata.sh + +# Create a new Lightsail instance with a different name +aws lightsail create-instances --instance-names $new_instance_name --availability-zone eu-central-1a --blueprint-id ubuntu_22_04 --bundle-id small_3_0 --user-data file://userdata.sh +sleep 600 +# Wait for the new instance to be ready +wait_for_instance_ready $new_instance_name + +# Open necessary ports on the instance +aws lightsail open-instance-public-ports --port-info fromPort=3000,toPort=3000,protocol=TCP --instance-name $new_instance_name + +# Attach the new instance to the load balancer +add_instance_to_load_balancer $new_instance_name grafana-lb + +# Wait for the new instance to be healthy on the load balancer +# wait_for_lb_instance_healthy grafana-lb $new_instance_name +sleep 90 + +# If a previous instance existed, detach it from the LB and then delete it +if [ "$previous_instance_exists" == "true" ]; then + aws lightsail detach-instances-from-load-balancer --load-balancer-name grafana-lb --instance-names $instance_name + delete_lightsail_instance $instance_name +fi + +# Rename the new instance to the original instance name +# aws lightsail update-instance-name --instance-name $new_instance_name --new-instance-name $instance_name + +echo "Deployment completed!" diff --git a/.github/tvarit/deploy_to_dev_30.sh b/.github/tvarit/deploy_to_dev_30.sh deleted file mode 100644 index c36720c65f..0000000000 --- a/.github/tvarit/deploy_to_dev_30.sh +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env bash -#test commit -set -e - -PREFIX=$1 -if [ -z "${PREFIX}" ]; then - echo "Usage .github/tvarit/deploy_to_dev_sk.sh " - exit 1 -fi - -validate_lightsail_instance() { - instance_name="$1" - - # Get the instance information - instance_info=$(aws lightsail get-instance --instance-name "$instance_name" 2>/dev/null) - - local exit_code=$? - echo $exit_code - -} - -delete_lightsail_instance() { - instance_name="$1" - - aws lightsail delete-instance --instance-name $instance_name - -} - -function add_instance_to_load_balancer() { - local instance_name="$1" - local load_balancer_name="$2" - - aws lightsail attach-instances-to-load-balancer --load-balancer-name "$2" --instance-names "$1" - -} - -function check_load_balancer_existence() { - local load_balancer_name="$1" - - aws lightsail get-load-balancer --load-balancer-name "$load_balancer_name" >/dev/null 2>&1 - - local exit_code=$? - echo $exit_code - -} - -function create_load_balancer() { - local load_balancer_name="$1" - local instance_port="$2" - - #aws lightsail create-load-balancer-tls-certificate --load-balancer-name "$load_balancer_name" >/dev/null 2>&1 - - aws lightsail create-load-balancer \ - --load-balancer-name "$load_balancer_name" \ - --instance-port "$instance_port" - -} - -aws lightsail get-certificates --certificate-name ${PREFIX}-tvarit-com > /dev/null - -echo "Creating production database..." -aws lightsail create-relational-database \ - --relational-database-name ${PREFIX}-grafana-db \ - --availability-zone ${AWS_DEFAULT_REGION}a \ - --relational-database-blueprint-id mysql_8_0 \ - --relational-database-bundle-id micro_1_0 \ - --preferred-backup-window 00:00-00:30 \ - --preferred-maintenance-window Sun:01:00-Sun:01:30 \ - --master-database-name grafana \ - --master-username grafana \ - --no-publicly-accessible || : - -echo "Waiting for database to be available..." -for run in {1..60}; do - state=$(aws lightsail get-relational-database --relational-database-name ${PREFIX}-grafana-db --output text --query 'relationalDatabase.state') - if [ "${state}" == "available" ]; then - break - fi - echo "Waiting for database to be available..." - sleep 60 -done - -if [ "${state}" != "available" ]; then - echo "Database not created in 60 mins" - exit 1 -fi - -echo "Creating staging database..." -aws lightsail create-relational-database-from-snapshot \ - --relational-database-name ${PREFIX}-next-grafana-db \ - --source-relational-database-name ${PREFIX}-grafana-db \ - --use-latest-restorable-time || : - -echo "Waiting for database to be available..." -for run in {1..60}; do - state=$(aws lightsail get-relational-database --relational-database-name ${PREFIX}-next-grafana-db --output text --query 'relationalDatabase.state') - if [ "${state}" == "available" ]; then - break - fi - echo "Waiting for database to be available..." - sleep 60 -done - -if [ "${state}" != "available" ]; then - echo "Database not created in 60 mins" - exit 1 -fi - -DB_ENDPOINT=$(aws lightsail get-relational-database --relational-database-name ${PREFIX}-next-grafana-db --output text --query 'relationalDatabase.masterEndpoint.address') -DB_PASSWORD=$(aws lightsail get-relational-database-master-user-password --relational-database-name ${PREFIX}-next-grafana-db --output text --query masterUserPassword) -#SIGNING_SECRET=$(aws secretsmanager get-secret-value --secret-id grafana-signing-secret --output text --query SecretString) - -#AWS-030 -AWS_ACCESS_KEY=$(aws secretsmanager get-secret-value --secret-id /credentials/grafana-user/access-key --output text --query SecretString) -AWS_SECRET_KEY=$(aws secretsmanager get-secret-value --secret-id /credentials/grafana-user/secret-key --output text --query SecretString) - -echo "Building docker image..." -docker build --tag grafana/grafana:next-${PREFIX} . - -cd .github/tvarit/conf/prod/ -echo "Downloading plugins..." -rm -rf plugins -aws s3 sync s3://com.tvarit.grafana.artifacts/grafana-plugins plugins -find plugins/ -type f -name *.tar.gz -exec bash -c 'cd $(dirname $1) && tar -xf $(basename $1) && rm $(basename $1); cd -' bash {} \; - -echo "Finalising docker image..." -cp grafana.ini.template grafana.ini -sed -i "s##next-${PREFIX}.tvarit.com#g" grafana.ini -sed -i "s##https://next-${PREFIX}.tvarit.com/#g" grafana.ini -sed -i "s##${SIGNING_SECRET}#g" grafana.ini -sed -i "s##${DB_ENDPOINT}#g" grafana.ini -sed -i "s##$(echo ${DB_PASSWORD} | sed 's/#/\\#/g' | sed 's/&/\\&/g')#g" grafana.ini -sed -i "s##${OAUTH_CLIENT_ID}#g" grafana.ini -sed -i "s##${OAUTH_CLIENT_SECRET}#g" grafana.ini -sed -i "s##${SMTP_HOST}#g" grafana.ini -sed -i "s##${SMTP_USER}#g" grafana.ini -sed -i "s##${SMTP_PASSWORD}#g" grafana.ini -sed -i "s##[BETA] Tvarit AI Platform#g" grafana.ini - -cp cloudwatch.json.template cloudwatch.json -sed -i "s##next-${PREFIX}.tvarit.com#g" cloudwatch.json - -cp Dockerfile.template Dockerfile -sed -i "s##grafana/grafana:next-${PREFIX}#g" Dockerfile -sed -i "s##${AWS_ACCESS_KEY}#g" Dockerfile -sed -i "s##${AWS_SECRET_KEY}#g" Dockerfile -sed -i "s##${AWS_DEFAULT_REGION}#g" Dockerfile -docker build --tag grafana/grafana:next-${PREFIX} . - -#push Docker image to ECR -echo "push docker image to ECR........." -aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 047870419389.dkr.ecr.eu-central-1.amazonaws.com -docker tag grafana/grafana:next-${PREFIX} 047870419389.dkr.ecr.eu-central-1.amazonaws.com/lightsail:latest -docker push 047870419389.dkr.ecr.eu-central-1.amazonaws.com/lightsail:latest - -instance_name=grafana-${PREFIX} -static_ip_name=grafana-ip-${PREFIX} - -return_value_instance=$(validate_lightsail_instance $instance_name) - -if [ $return_value_instance -eq 0 ]; then - echo "instance already exist" - echo "deleting existing lightsail instance" - delete_lightsail_instance $instance_name -fi - -echo "Creating lightsail instance!!!!!!" -cp lightsail.sh userdata.sh -sed -i "s##${AWS_ACCESS_KEY}#g" userdata.sh -sed -i "s##${AWS_SECRET_KEY}#g" userdata.sh - -aws lightsail create-instances --instance-names grafana-${PREFIX} --availability-zone eu-central-1a --blueprint-id ubuntu_22_04 --bundle-id nano_2_0 --user-data file://userdata.sh -echo "waiting for user data to be executed in the instance" -sleep 300 - -#check if load balancer exist -return_value=$(check_load_balancer_existence "grafana-lb") -echo $return_value - if [[ $return_value -eq 0 ]]; then - echo "load balancer exist" - else - echo "creating Load Balancer" - create_load_balancer "grafana-lb" 80 - fi - -echo "waiting for server to up and running!!!!!!!!!!!" -sleep 180 -echo "adding instance to load balancer" -add_instance_to_load_balancer grafana-${PREFIX} grafana-lb - -aws lightsail open-instance-public-ports --port-info fromPort=3000,toPort=3000,protocol=TCP --instance-name grafana-${PREFIX} - -echo "waiting for instance to be attach with load balancer" -sleep 120 diff --git a/.github/workflows/deploy-030.yml b/.github/workflows/deploy-016.yml similarity index 55% rename from .github/workflows/deploy-030.yml rename to .github/workflows/deploy-016.yml index d05c9a4fa3..3ff5dd6a69 100644 --- a/.github/workflows/deploy-030.yml +++ b/.github/workflows/deploy-016.yml @@ -1,22 +1,24 @@ -name: Deploy to 030 +name: Deploy to Dev on: workflow_dispatch: jobs: deploy_to_dev: - runs-on: ubuntu-latest + runs-on: self-hosted environment: development env: AWS_DEFAULT_REGION: eu-central-1 - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_030 }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_030 }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} OAUTH_CLIENT_ID: ${{ secrets.OAUTH_CLIENT_ID }} OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET }} SMTP_HOST: ${{ secrets.SMTP_HOST }} SMTP_USER: ${{ secrets.SMTP_USER }} SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} + AWS_ACCESS_KEY_ID_016: ${{secrets.AWS_ACCESS_KEY_ID_016}} + AWS_SECRET_KEY_ID_016: ${{secrets.AWS_SECRET_KEY_ID_016}} steps: - uses: actions/checkout@v2 - run: | - bash .github/tvarit/deploy_to_dev_30.sh test \ No newline at end of file + bash .github/tvarit/deploy_to_dev_16.sh test \ No newline at end of file diff --git a/conf/defaults.ini b/conf/defaults.ini index f7bade7dbf..78f51a8c75 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -141,7 +141,7 @@ logging = false # How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds. # This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set. -timeout = 30 +timeout = 300 # How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds. dialTimeout = 10 @@ -226,7 +226,7 @@ application_insights_endpoint_url = disable_initial_admin_creation = false # default admin user, created on startup -admin_user = admin +admin_user = 3dc9dc84-ae47-4488-b068-53c4bf5cebf7 # default admin password, can be changed before first start of grafana, or in profile settings admin_password = admin @@ -478,16 +478,17 @@ allowed_organizations = #################################### Azure AD OAuth ####################### [auth.azuread] -name = Azure AD -enabled = false -allow_sign_up = true -client_id = some_client_id -client_secret = +name = Maxion +enabled = true +;allow_sign_up = true +client_id = 190aea98-f89e-4fd6-b2d2-89e16b490ff1 +client_secret = 0sK8Q~LYvnVZRRZruiVodqa~.KNygugwLHm34bNg +auth_url = https://login.microsoftonline.com/54067617-1ace-44a2-b7d9-f59327ef106d/oauth2/v2.0/authorize +token_url = https://login.microsoftonline.com/54067617-1ace-44a2-b7d9-f59327ef106d/oauth2/v2.0/token scopes = openid email profile -auth_url = https://login.microsoftonline.com//oauth2/v2.0/authorize -token_url = https://login.microsoftonline.com//oauth2/v2.0/token -allowed_domains = -allowed_groups = +role_attribute_strict = false +;allowed_domains = +;allowed_groups = #################################### Okta OAuth ####################### [auth.okta] @@ -1117,4 +1118,4 @@ enabled = true default_baselayer_config = # Enable or disable loading other base map layers -enable_custom_baselayers = true \ No newline at end of file +enable_custom_baselayers = true diff --git a/lightsail.sh b/lightsail.sh deleted file mode 100644 index b020b78eab..0000000000 --- a/lightsail.sh +++ /dev/null @@ -1,24 +0,0 @@ -sudo su -apt update -snap install docker - -cd /home/ubuntu -curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" -apt install unzip -y -unzip awscliv2.zip -./aws/install -sleep 300 -rm -rf awscliv2.zip - -#with only ECR pull access. TODO: update -AWS_ACCESS_KEY_ID="AKIAQWJKMUG6VSEUIM54" -AWS_SECRET_ACCESS_KEY="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" -AWS_REGION="eu-central-1" - -aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID -aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY - -docker login -u AWS -p $(aws ecr get-login-password --region eu-central-1) 047870419389.dkr.ecr.eu-central-1.amazonaws.com -docker pull 047870419389.dkr.ecr.eu-central-1.amazonaws.com/lightsail:latest -docker images >> test.txt #for testing -docker run -d -p 80:3000 047870419389.dkr.ecr.eu-central-1.amazonaws.com/lightsail:latest \ No newline at end of file diff --git a/pkg/login/social/azuread_oauth.go b/pkg/login/social/azuread_oauth.go index 9ce173b65f..3f000411db 100644 --- a/pkg/login/social/azuread_oauth.go +++ b/pkg/login/social/azuread_oauth.go @@ -69,8 +69,8 @@ func (s *SocialAzureAD) UserInfo(client *http.Client, token *oauth2.Token) (*Bas return nil, errors.New("error getting user info: no email found in access token") } - role := extractRole(claims, s.autoAssignOrgRole) - logger.Debug("AzureAD OAuth: extracted role", "email", email, "role", role) + /* role := extractRole(claims, s.autoAssignOrgRole) + logger.Debug("AzureAD OAuth: extracted role", "email", email, "role", role) */ groups, err := extractGroups(client, claims, token) if err != nil { @@ -87,7 +87,7 @@ func (s *SocialAzureAD) UserInfo(client *http.Client, token *oauth2.Token) (*Bas Name: claims.Name, Email: email, Login: email, - Role: string(role), + Role: "", /* string(role), */ Groups: groups, }, nil } @@ -117,7 +117,7 @@ func extractEmail(claims azureClaims) string { return claims.Email } - +/* func extractRole(claims azureClaims, autoAssignRole string) models.RoleType { if len(claims.Roles) == 0 { return models.RoleType(autoAssignRole) @@ -146,7 +146,7 @@ func hasRole(roles []string, role models.RoleType) bool { } return false } - +*/ type getAzureGroupRequest struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` } diff --git a/pkg/services/ngalert/notifier/channels/email.go b/pkg/services/ngalert/notifier/channels/email.go index 75000c0d84..df867d6913 100644 --- a/pkg/services/ngalert/notifier/channels/email.go +++ b/pkg/services/ngalert/notifier/channels/email.go @@ -80,7 +80,7 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, en.log.Debug("failed to parse external URL", "url", en.tmpl.ExternalURL.String(), "err", err.Error()) } - checkUrl := func (input string) bool { + checkUrl := func(input string) bool { pattern := `^(https?|ftp)://[^\s/$.?#].[^\s]*$` regex := regexp.MustCompile(pattern) return regex.MatchString(input) @@ -106,7 +106,20 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, } } } - Dispatcher := func(data ExtendedData, isNoDataAlert bool) (bool, error) { + Dispatcher := func(data ExtendedData) (bool, error) { + dataAlerts := []ExtendedAlert{} + noDataAlerts := []ExtendedAlert{} + for _, alert := range data.Alerts { + if alert.Labels["alertname"] == "DatasourceNoData" { + newAlert := ExtendedAlert{} + deepcopier.Copy(alert).To(&newAlert) + noDataAlerts = append(noDataAlerts, newAlert) + } else { + newAlert := ExtendedAlert{} + deepcopier.Copy(alert).To(&newAlert) + dataAlerts = append(dataAlerts, newAlert) + } + } cmd := &models.SendEmailCommandSync{ SendEmailCommand: models.SendEmailCommand{ Subject: title, @@ -114,13 +127,14 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, "Title": title, "Message": tmpl(en.Message), "Status": data.Status, - "Alerts": data.Alerts, + "Alerts": dataAlerts, "GroupLabels": data.GroupLabels, "CommonLabels": data.CommonLabels, "CommonAnnotations": data.CommonAnnotations, "ExternalURL": data.ExternalURL, "RuleUrl": ruleURL, "AlertPageUrl": alertPageURL, + "NoDataAlerts": noDataAlerts, }, To: en.Addresses, SingleEmail: en.SingleEmail, @@ -131,49 +145,20 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, if tmplErr != nil { en.log.Warn("failed to template email message", "err", tmplErr.Error()) } - if isNoDataAlert { - cmd.Subject = "No Data Alert" - cmd.Template = "no_data_alert" - } + if err := bus.Dispatch(ctx, cmd); err != nil { return false, err } return true, nil } - dataAlerts := []ExtendedAlert{} - noDataAlerts := []ExtendedAlert{} - for _, alert := range data.Alerts { - if alert.Labels["alertname"] == "DatasourceNoData" { - newAlert := ExtendedAlert{} - deepcopier.Copy(alert).To(&newAlert) - noDataAlerts = append(noDataAlerts, newAlert) - } else { - newAlert := ExtendedAlert{} - deepcopier.Copy(alert).To(&newAlert) - dataAlerts = append(dataAlerts, newAlert) - } - } - if len(dataAlerts) > 0 { - newData := &ExtendedData{} - deepcopier.Copy(data).To(newData) - newData.Alerts = dataAlerts - ok, err := Dispatcher(*newData, false) - if !ok { - return ok, err - } - } - if len(noDataAlerts) > 0 { - newData := &ExtendedData{} - deepcopier.Copy(data).To(newData) - newData.Alerts = noDataAlerts - ok, err := Dispatcher(*newData, true) - if !ok { - return ok, err - } + ok, err := Dispatcher(*data); + if !ok { + return ok, err } + data.Alerts = ExtendedAlerts{} return true, nil } func (en *EmailNotifier) SendResolved() bool { return !en.GetDisableResolveMessage() -} \ No newline at end of file +} diff --git a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx index e9259f2147..4c8b2ac205 100644 --- a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx @@ -53,7 +53,7 @@ export const SaveDashboardForm: React.FC = ({ dashboard, )} {(hasVariableChanged || hasTimeChanged) &&
} -