icinga2 notifications to cachet - notifications

I would like to share with you a way to send notifications from icinga2 to cachet via the API.
Icinga2 version : 2.4.10-1
Cachet version : 2.3.9
First of all, you have to know which component ID you want to use (in my case, because you can update component by name)
To get the component ID, you can use the curl command :
curl --insecure --request GET --url https://URL/api/v1/components -H "X-Cachet-Token: TOKEN"
URL : The URL of your cachet installation
TOKEN : The Token of the member in Cachet
Create command in /etc/icinga2/conf.d/commands.conf
object NotificationCommand "cachet-incident-notification-v2" {
import "plugin-notification-command"
command = [ PluginDir + "/cachet-notification-v2.sh" ]
env = {
"SERVICESTATE" = "$service.state$"
}
}
Create notification template in /etc/icinga2/conf.d/templates.conf
template Notification "cachet-incident-notification-v2" {
command = "cachet-incident-notification-v2"
states = [ OK, Warning, Critical, Unknown ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd,
DowntimeStart, DowntimeEnd, DowntimeRemoved ]
/*
period = "24x7"
*/
interval = 0
}
Create notification in /etc/icinga2/conf.d/notifications.conf
apply Notification "cachet-incident-notification-v2" to Service {
import "cachet-incident-notification-v2"
user_groups = host.vars.notification.pager.groups
assign where service.vars.cachetv2 == "1" && host.vars.cachetv2 == "1"
interval = 0 # Disable Re-notification
}
Add variable in your check service in /etc/icinga2/conf.d/service/your/service.conf
[...]
vars.cachetv2 = "1"
[...]
Add variable in your host config file in /etc/icinga2/conf.d/hosts/your/host
[...]
vars.cachetv2 = "1"
[...]
Create the script in /usr/lib/nagios/plugins/cachet-notification-v2.sh
#!/bin/bash
# Some Constants
NOW="$(date +'%d/%m/%Y')"
CACHETAPI_URL="https://URL/api/v1/components/<ID DU COMPOSANT>"
CACHETAPI_TOKEN="TOKEN><"
# Map Notification states for icinga2
# OK - 1 operational
# Warning - 3 Partial outage
# Critical - 4 Major outage
# Unknown - 2 Performance issues
case "$SERVICESTATE" in
'OK')
COMPONENT_STATUS=1
;;
'WARNING')
COMPONENT_STATUS=3
;;
'CRITICAL')
COMPONENT_STATUS=4
;;
'UNKNOWN')
COMPONENT_STATUS=2
;;
esac
curl -X PUT -H "Content-Type: application/json;" -H "X-Cachet-Token: ${CACHETAPI_TOKEN}" -d '{"status": "'"${COMPONENT_STATUS}"'"}' ${CACHETAPI_URL} -k
PS : Give the execution permission to the script
Check the syntax and reload
/etc/init.d/icinga2 checkconfig && /etc/init.d/icinga2 reload
The result :
When your check results in "CRITICAL", the status in Cachet will be MAJOR ISSUE
When your check results in "WARNING", the status in Cachet will be PARTIAL ISSUE
When your check results in "OK", the status in Cachet will be OPERATIONAL
When your check results in "UNKNOWN", the status in Cachet will be PERFORMANCE DELAY
I hope it will help.
Nicolas B.

Related

Run a job via the rundeck API with parameters in postman

I am trying around with the Rundeck API. I was able to get a simple Job running. But now I am trying to run a job, that has a job option. The job option for this job is an IP, so Rundeck starts the Job only on this machine.
When I use the API, I don't know how to set the parameter. I am using the tool Postman, where I only receive the message "Job options were not valid: Option 'IP' is required".
I looked it up on the rundeck documentation and I found this for postman
In the rundeck documentation is this example:
argString: argument string to pass to the job, of the form: -opt value -opt2 value ....
How can I use it for my IP?
Using this Rundeck Job Definition:
- defaultTab: nodes
description: ''
executionEnabled: true
id: 9f04657a-eaab-4e79-a5f3-00d3053f6cb0
loglevel: INFO
name: HelloWorld
nodeFilterEditable: false
options:
- name: opt1
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: echo "hello ${option.opt1}"
keepgoing: false
strategy: node-first
uuid: 9f04657a-eaab-4e79-a5f3-00d3053f6cb0
And based on this, you can do it by putting the options in JSON format (json body) on Postman:
{
"options": {
"opt1":"world"
}
}
This is the code snipped in cURL format:
curl --location --request POST 'pop-os:4440/api/38/job/9f04657a-eaab-4e79-a5f3-00d3053f6cb0/run' \
--header 'X-Rundeck-Auth-Token: GuaoD6PtH5BhobhE3bAPo4mGyfByjNya' \
--header 'Content-Type: application/json' \
--header 'Cookie: JSESSIONID=node01tz8yvp4gjkly8kpj18h8u5x42.node0' \
--data-raw '{
"options": {
"opt1":"world"
}
}'
Check how looks on Postman.

Apple Connect API financialReport Returning 403 The resource 'financeReports' does not allow 'CREATE'. Allowed operations are: GET_COLLECTION"

Trying to pull financial reports from apple connect api and getting a 403 for CREATE operation, this is not documented :/. anyone know how I use a GET_COLLECTIONS operations here with cURL?
exec("curl -v -X POST -H 'Authorization: Bearer {$token}' \"https://api.appstoreconnect.apple.com/v1/financeReports\" -d 'regionCode=Americas&reportDate=2020-01&reportType=FINANCIAL&vendorNumber=xxx&' -o output");
Response:
{
"errors" : [ {
"id" : "bb9e260c-c3d4-4df9-b78e-f34dfd42c449",
"status" : "403",
"code" : "FORBIDDEN_ERROR",
"title" : "The given operation is not allowed",
"detail" : "The resource 'financeReports' does not allow 'CREATE'. Allowed operations are: GET_COLLECTION"
} ]
}
response
You need to use GET, Not POST
exec("curl -v X GET -H 'Authorization: Bearer {$token}' \"https://api.appstoreconnect.apple.com/v1/financeReports?regionCode=Americas&reportDate=2020-01&reportType=FINANCIAL&vendorNumber=xxx\" -o output");
should do the trick!

How to store Terraform provisioner "local-exec" output in local variable and use variable value in "remote-exec"

I am working with Terraform provisionar. and in one scenario I need to execute a 'local-exec' provisionar and use the output [This is array of IP addesses] of the command into next 'remote-exec' provisionar.
And i am not able to store the 'local-exec' provisionar output in local variable to use later. I can store it in local file but not in intermediate variable
count = "${length(data.local_file.instance_ips.content)}"
this is not working.
resource "null_resource" "get-instance-ip-41" {
provisioner "local-exec" {
command = "${path.module}\\scripts\\findprivateip.bat > ${data.template_file.PrivateIpAddress.rendered}"
}
}
data "template_file" "PrivateIpAddress" {
template = "/output.log"
}
data "local_file" "instance_ips" {
filename = "${data.template_file.PrivateIpAddress.rendered}"
depends_on = ["null_resource.get-instance-ip-41"]
}
output "IP-address" {
value = "${data.local_file.instance_ips.content}"
}
# ---------------------------------------------------------------------------------------------------------------------
# Update the instnaces by installing newrelic agent using remote-exec
# ---------------------------------------------------------------------------------------------------------------------
resource "null_resource" "copy_file_newrelic_v_29" {
depends_on = ["null_resource.get-instance-ip-41"]
count = "${length(data.local_file.instance_ips.content)}"
triggers = {
cluster_instance_id = "${element(values(data.local_file.instance_ips.content[count.index]), 0)}"
}
provisioner "remote-exec" {
connection {
agent = "true"
bastion_host = "${aws_instance.bastion.*.public_ip}"
bastion_user = "ec2-user"
bastion_port = "22"
bastion_private_key = "${file("C:/keys/nvirginia-key-pair-ajoy.pem")}"
user = "ec2-user"
private_key = "${file("C:/keys/nvirginia-key-pair-ajoy.pem")}"
host = "${self.triggers.cluster_instance_id}"
}
inline = [
"echo 'license_key: 34adab374af99b1eaa148eb2a2fc2791faf70661' | sudo tee -a /etc/newrelic-infra.yml",
"sudo curl -o /etc/yum.repos.d/newrelic-infra.repo https://download.newrelic.com/infrastructure_agent/linux/yum/el/6/x86_64/newrelic-infra.repo",
"sudo yum -q makecache -y --disablerepo='*' --enablerepo='newrelic-infra'",
"sudo yum install newrelic-infra -y"
]
}
}
Unfortunately you can't. The solution I have found is to instead use an external data source block. You can run a command from there and retrieve the output(s), the only catch is that the command needs to produce json to standard output (stdout). See documentation here. I hope this is some help to others trying to solve this problem.

Fiware Orion context broker subscription notification issue

I'm using orion context broker GE image orion-psb-image-R5.4 version 1.7.0 and I registered a device entity in it , then i implemented in my raspberry pi simple python server script that listens to any incoming message and print it on the Pi's logs . then i sent a subscription message to the context broker to let my raspberry pi subscribe to its corresponding entity in the context broker. The issue is that whenever i update the condition attributes in the entity in the context broker , they're supposed to trigger a notification to the raspberry pi and then the server script in the PI print the notification in the Pi's logs . But what really happens is that the context broker may trigger the notification for several times and then suddenly stops sending any notification when any additional change is applied to the condition attribute , and on every attempt i make i retrieve the subscription status in the context broker and i find that there was a failure stated by the lastfailure attribute giving me the time of my last failed attempt.
I thought the problem could be the connection to my Pi or even in the server script itself but when i launched direct requests from my terminal to the raspberry pi , it prints the all messages immediately even when the update is made from a remote place . So i concluded that the problem is definitely with the context broker and the notification process of the subscription itself .
Here's the subscription request i made :
curl -v contextbrokeraddress:1026/v2/subscriptions -s -S --header "Fiware-Service: XYZ" --header "Fiware-ServicePath: /XYZ" --header 'Content-Type: application/json' \
-d #- <<EOF
{
"description": " Try",
"subject": {
"entities": [
{
"id": "Controller1",
"type": "Controller"
}
],
"condition": {
"attrs": [
"switch",
"datashow"
]
}
},
"notification": {
"http": {
"url": "http://raspberryPiaddress:8080"
},
"attrs": [
"switch",
"datashow"
]
},
"expires": "2040-01-01T14:00:00.00Z",
"throttling": 5
}
EOF
now when the switch attribute is updated with a different value , it may trigger the notification to the raspberry pi for the first time only but then fails on any following attempts.
this is the simple python script that listens to the incoming notifications and print it in its logs:
import socket
HOST, PORT = '', 8080
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
while True:
print "listening on port 8080"
client_connection, client_address = listen_socket.accept()
print "notified"
request = client_connection.recv(1024)
print request
client_connection.close()
And this is how the notification from the context broker is printed on the Pi's logs in its successful times:
listening on port 8080
notified
POST / HTTP/1.1
User-Agent: orion/1.7.0 libcurl/7.19.7
Host: raspberryPiaddress:8080
fiware-service: XYZ
Fiware-ServicePath: /XYZ
X-Auth-Token: token
Accept: application/json
Content-length: 208
Content-type: application/json; charset=utf-8
Fiware-Correlator: f48ced60-1069-11e7-b743-fa163e7c4daf
Ngsiv2-AttrsFormat: normalized
{"subscriptionId":"58cd49191e9c000de6ea89c7","data":[{"id":"Controller1","type":"Controller","switch":{"type":"command","value":"OFF","metadata":{}},"datashow":{"type":"string","value":"OFF","metadata":{}}}]}
And when the notification is not received on any following updates on the entity , i check that it was failure by retrieving the subscription status which states that a failure happened in the context broker on sending the notification at the exact time of my attempt. This the status i retrieve to check that:
[
{
"description": " Try",
"expires": "2040-01-01T14:00:00.00Z",
"id": "58cd49191e9c000de6ea89c7",
"notification": {
"attrs": [
"switch",
"datashow"
],
"attrsFormat": "normalized",
"http": {
"url": "http://ahmadpi.ddns.net:8080"
},
**"lastFailure": "2017-03-24T08:22:23.00Z",**
"lastNotification": "2017-03-24T08:22:18.00Z",
"lastSuccess": "2017-03-23T22:09:33.00Z",
"timesSent": 66
},
"status": "failed",
"subject": {
"condition": {
"attrs": [
"switch",
"datashow"
]
},
"entities": [
{
"id": "Controller1",
"type": "Controller"
}
]
},
"throttling": 5
}
]
the problem now seems to be relating to the context broker and the way the subscription/notification processes are handled inside it . Now, i want to know whether the problem regards the context broker image version that i used or whether it regards something else . I just want to know where's the problem and how it can be handled please and thanks so much.
Although I'm not fully sure as don't have all the inputs (specially, CB log traces), by "it worked well as I said but sometimes stops for some reasons" (see comments thread in the question post) I tend to think is some networking/connectivity problem, not directly related with Orion Context Broker.

Icinga2 notifications does not execute notification command

I'm trying to configure icinga2 notification. I restart icinga2 and no error occurs. But my notification command does not execute. I defined user, template and applied notification to host, notification command for notification (as below) and turned on notification feature, i don't know why my script did not run. Anyone in forum used to configure icinga2 notification can give me full steps to configure icinga notification.
Notification Command
object NotificationCommand "test-notification" {
import "plugin-notification-command"
command = [ "/etc/icinga2/scripts/test.sh" ]}
Notification template
template Notification "generic-notification" {
command = "test-notification"
period = "test-24x7"
user_groups = [ "icinga" ]}
User
object User "icinga" {
import "generic-user"
display_name = "Icinga 2 Admin"
enable_notifications = true
email = "icinga#localhost"}
Notification
apply Notification "test-notification" to Host {
import "generic-notification"
users = [ "icinga" ]
assign where host.display_name}
You should try to verify that the execution is not working if not happen yet. Is it executable (chmod +x test.sh)?:
In your test.sh you could do something like
echo "script executed" >> /tmp/doesmyscriptrun.txt
Have a look to your file:
cat /tmp/doesmyscriptrun.txt