Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ SUMSUB_APP_TOKEN=
SUMSUB_SECRET_KEY=
SUMSUB_JWT_SECRET_KEY=

EMAIL_TEMPLATES_PATH="./templates/html/"
EMAIL_TEMPLATES_PATH="./templates/html/"
EE_CHAINSTORE_API_URL=
13 changes: 13 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ func startApi(ctx *cli.Context) error {
c.Start()
}

offlineNodeTiming, found := config.Config.GetOfflineNodesCronJobTiming(nodeAddress)
if found {
if err := service.ValidateOfflineNodesNotifierConfig(); err != nil {
return errors.New("invalid offline nodes notifier config: " + err.Error())
}
c := cron.New(cron.WithChain(cron.SkipIfStillRunning(cron.DefaultLogger)))
_, err = c.AddFunc(offlineNodeTiming, service.NotifyOfflineLinkedNodes)
if err != nil {
return errors.New("error while starting offline nodes cronjob: " + err.Error())
}
c.Start()
}

monthlyNodeTiming, found := config.Config.GetMonthlyCronJobTiming(nodeAddress)
if found {
c := cron.New()
Expand Down
1 change: 1 addition & 0 deletions config/config.devnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
]
},
"DeeployApi": "https://devnet-deeploy-api.ratio1.ai/get_oracle_job_details",
"OraclesApi": "https://devnet-oracle.ratio1.ai",
"CronJobTiming": {},
"ChainID": 84532,
"BuyLimitUSD": {
Expand Down
7 changes: 7 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type GeneralConfig struct {
Oblio Oblio
Infura Infura
DeeployApi string
OraclesApi string
NDContractAddress string
R1ContractAddress string
USDCContractAddress string
Expand All @@ -38,6 +39,7 @@ type GeneralConfig struct {
TeamAddresses []string
BuyLicenseInvoiceCronJobTiming map[string]string
DailyCronJobTiming map[string]string
OfflineNodesCronJobTiming map[string]string
MonthlyCronJobTiming map[string]string
AdminAddresses []string
EmailTemplatesPath string
Expand Down Expand Up @@ -292,3 +294,8 @@ func (c *GeneralConfig) GetMonthlyCronJobTiming(nodeAddress string) (string, boo
nodeTiming, found := c.MonthlyCronJobTiming[nodeAddress]
return nodeTiming, found
}

func (c *GeneralConfig) GetOfflineNodesCronJobTiming(nodeAddress string) (string, bool) {
nodeTiming, found := c.OfflineNodesCronJobTiming[nodeAddress]
return nodeTiming, found
}
9 changes: 9 additions & 0 deletions config/config.mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@
"0x2539fDD57f93b267E58d5f2E6F77063C0230F6F4": "40 * * * *",
"0xdc4fDFd5B86aeA7BaB17d4742B7c39A2728Ff59B": "50 * * * *"
},
"OfflineNodesCronJobTiming": {
"0xe240d9cf8893d6bE9fb3Ac4C9CE1E504343b64a0": "05 * * * *",
"0xA48C80afb9eC73A9F6731a9Cea6774Ed6249a922": "15 * * * *",
"0x3B373897136687af87DDbF65662Eb7004090eAF8": "25 * * * *",
"0x7388fC301eb7CF6743ecF9e6c781210758669bAD": "35 * * * *",
"0x2539fDD57f93b267E58d5f2E6F77063C0230F6F4": "45 * * * *",
"0xdc4fDFd5B86aeA7BaB17d4742B7c39A2728Ff59B": "55 * * * *"
},
"MonthlyCronJobTiming": {
"0xe240d9cf8893d6bE9fb3Ac4C9CE1E504343b64a0": "0 08 1 * *",
"0xA48C80afb9eC73A9F6731a9Cea6774Ed6249a922": "0 10 1 * *",
Expand All @@ -114,6 +122,7 @@
"CspUrl": "https://deeploy.ratio1.ai/account?tab=invoicing"
},
"DeeployApi": "https://deeploy-api.ratio1.ai/get_oracle_job_details",
"OraclesApi": "https://oracle.ratio1.ai",
"ViesApi": {
"BaseUrl": "https://viesapi.eu/api"
}
Expand Down
1 change: 1 addition & 0 deletions config/config.testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
]
},
"DeeployApi": "https://testnet-deeploy-api.ratio1.ai/get_oracle_job_details",
"OraclesApi": "https://testnet-oracle.ratio1.ai",
"CronJobTiming": {},
"ChainID": 84532,
"BuyLimitUSD": {
Expand Down
3 changes: 2 additions & 1 deletion deployScripts/deploy_devnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
'SUMSUB_JWT_SECRET_KEY':'',

'EMAIL_TEMPLATES_PATH':'./templates/html/',
'EE_CHAINSTORE_API_URL':'',
}

# Defining the assets of the application.
Expand Down Expand Up @@ -73,4 +74,4 @@
session.run(
wait=30, # wait for the user to stop the execution
close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
)
)
3 changes: 2 additions & 1 deletion deployScripts/deploy_mainnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'INFURA_SECRET':'',

'EMAIL_TEMPLATES_PATH':'./templates/html/',
'EE_CHAINSTORE_API_URL':'',
}

# Defining the assets of the application.
Expand Down Expand Up @@ -81,4 +82,4 @@
session.run(
wait=True, # wait for the user to stop the execution
close_pipelines=False # when the user stops the execution, the remote edge-node pipelines will be closed
)
)
3 changes: 2 additions & 1 deletion deployScripts/deploy_testnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
'SUMSUB_JWT_SECRET_KEY':'',

'EMAIL_TEMPLATES_PATH':'./templates/html/',
'EE_CHAINSTORE_API_URL':'',
}

# Defining the assets of the application.
Expand Down Expand Up @@ -73,4 +74,4 @@
session.run(
wait=30, # wait for the user to stop the execution
close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
)
)
59 changes: 59 additions & 0 deletions service/emailService.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
subjectNewBuyLicenseInvoice = "A new buy license invoice has been sent"
subjectNewInvoiceDraft = "New draft invoices have been issued"
subjectJobsEndingSoon = "Ratio1 - Jobs ending soon"
subjectNodesOffline = "Ratio1 - Linked nodes offline for more than 24h"
)

var (
Expand Down Expand Up @@ -239,6 +240,64 @@ func SendJobsEndingEmail(email string, jobs []EndingJob) error {
return callSendEmail(email, subjectJobsEndingSoon, body.String())
}

func SendOfflineNodesEmail(email string, nodes []OfflineNodeAlert) error {
if len(nodes) == 0 {
return nil
}

tmpl, err := templates.GetNodesOfflineEmailTemplate()
if err != nil {
return errors.New("error while retrieving email template: " + err.Error())
}

type offlineNodeTemplateRow struct {
Alias string
Address string
OfflineFor string
}

rows := make([]offlineNodeTemplateRow, 0, len(nodes))
for _, node := range nodes {
rows = append(rows, offlineNodeTemplateRow{
Alias: node.NodeAlias,
Address: node.NodeAddress,
OfflineFor: formatOfflineDuration(node.OfflineSeconds),
})
}

var body bytes.Buffer
err = tmpl.Execute(&body, struct {
Nodes []offlineNodeTemplateRow
NodesCount int
}{
Nodes: rows,
NodesCount: len(rows),
})
if err != nil {
return errors.New("error while executing email template: " + err.Error())
}

return callSendEmail(email, subjectNodesOffline, body.String())
}

func formatOfflineDuration(seconds int64) string {
if seconds <= 0 {
return "0m"
}

days := seconds / 86400
hours := (seconds % 86400) / 3600
minutes := (seconds % 3600) / 60

if days > 0 {
return fmt.Sprintf("%dd %dh %dm", days, hours, minutes)
}
if hours > 0 {
return fmt.Sprintf("%dh %dm", hours, minutes)
}
return fmt.Sprintf("%dm", minutes)
}

func callSendTextEmail(email, subject, text string) error {
msg := EmailMessage{
From: config.Config.Mail.FromEmail,
Expand Down
Loading
Loading