I wrote a powershell script for setting downtimes in our monitoring software "checkmk" and now I have to convert that so a bash script because we are switching from windows server to linux.
user will be "XXX" password will be "YYY" and the hostname will be "ZZZ"
For that I used the documentation from CheckMK: documentation for show sheduled downtimes documentation for setting a downtime
and in the end it looks like that:
<#
.Synopsis
Downtime per Rest API bei Check MK Setzen
.DESCRIPTION
Doku https://apt-omd-vip.ads.vhv.de/umbrella/check_mk/openapi/#operation/cmk.gui.plugins.openapi.endpoints.downtime.create_host_related_downtime
30 min Downtime Setzen = 1800 sekunden
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
#>
function set-Downtime
{
[CmdletBinding()]
[OutputType([int])]
Param
(
$USERNAME="XXX",
$PASSWORD="XXX",
[Parameter(Mandatory=$true)]
$HOSTNAME,
#Zeit soll die Downtime in Minuten angeben, wird dieseer Parameter leer gelassen wird Standdardmäßig 30min verwendet.
[Parameter(Mandatory=$false)]
[Int]$TIME=30
)
Begin
{
}
Process
{
#=============
# Abfrage der DownTimes, sonst kein Connect möglich
#=============
$headers = @{
‘Accept’ = ‘application/json’
‘Authorization’ = “Bearer $USERNAME $PASSWORD”
}
$body = @{
'host_name' = $HOSTNAME
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
$result = Invoke-RestMethod -uri “here was a URL” -Headers $headers -Body $body
#write-host($rest_uri)
#=============
# DownTime
#=============
$headers = @{
'Content-Type' = 'application/json'
‘Accept’ = ‘application/json’
‘Authorization’ = “Bearer $USERNAME $PASSWORD”
}
$datum_start = (get-date).AddHours(-2).ToString("u")
$datum_ende = (get-date).AddHours(-2).addminutes($TIME).ToString("u") ;
$comment = "$TIME min Restart Downtime, $EXTRAINFO"
$body =@{
start_time = $datum_start;
end_time = $datum_ende;
comment = $comment;
host_name = $HOSTNAME;
downtime_type = 'host';
} | ConvertTo-Json -Compress
$result = Invoke-RestMethod -Method Post -uri "here was a URL" -Headers $headers -Body $body
}
End
{
}
}
I apologize for the english-german mix in the script but in theory you shouldn't need my comments.
I reconstructed the command from this bash to powershell help blog Here is one time my bash script hole and after that I will only post the part I changed:
#!/bin/bash
##Variables
base_url='here was a URL'
request_url="$base_url/all"
post_url="$base_url/host"
user="XXX"
passwd="YYY"
hostname="ZZZ"
user_pass="$user:$passwd"
#header=["Accep"t = "application/json"
#"Authorisation" = "Bearer $user $passwd"]
#body1=["host_name" = "ZZZ"]
curl -u $user_pass -X GET --header 'Accept: application/json' -d {'host_name: ZZZ'} 'here was an URL'
as I am still unexperienced in bash I tried my decleration of variables with the '' and "" quotes because I am still not shure when to use what (but thats not the question here) Answer is following:
{"title": "You need to be authenticated to use the REST API.", "status": 401}
Next thing I tried was a header construct similar to my ps script:
header=( ["Accept"]="application/json" ["Authorization"]="Bearer XXX YYY")
curl --anyauth -X GET --header $header -d {'host_name: ZZZ'} 'here was an URL'
the answer this times was way longer but in the end I got the same error message:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "censored doc url">
<html>
<!-- FileName: index.html
Language: [en]
-->
<!--Head-->
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<title>McAfee Web Gateway - Notification</title>
<script src="censored" type="text/vascript" ></script>
<link rel="stylesheet" href="censored" />
</head>
<!--/Head-->
<!--Body-->
<body onl oad="swOnLoad();">
<table class='bodyTable'>
<tr>
<td class='bodyData' background='censored'>
<!--Logo-->
<table class='logoTable'>
<tr>
<td class='logoData'>
<a href='http://www.mcafee.com'>
<img src='censored'>a>
</td>
</tr>
</table>
<!--/Logo-->
<!--Contents-->
<!-- FileName: authenticationrequired.html
Language: [en]
-->
<!--Title-->
<table class='titleTable' background='censored.jpg'>
<tr>
<td class='titleData'>
Authentication Required
</td>
</tr>
</table>
<!--/Title-->
<!--Content-->
<table >
<tr>
<td >
You must be authenticated to access this URL.
</td>
</tr>
</table>
<script language="javascript" type="text/javascript">
urlprotocol = "http";
statuscode=407;
if(statuscode==401 && urlprotocol == "ftp"){
document.write("<form name=\"ftpform\" method=\"get\" action=\"\">");
document.write("<table class=\"contentData\">");
document.write("<tr><td class=\"contentData\" colspan=2>Please enter youcredentials in the form below and click \"Access FTP\" button if your browser esn't present authentication prompt for FTP sites.</td></tr>");
document.write("<tr><td class=\"contentData\">Username:</td><td><input te=\"text\" id=\"ftpUsername\" name=\"ftpUsername\" size=40 /></td></tr>");
document.write("<tr><td class=\"contentData\">Password:</td><td><input te=\"password\" id=\"ftpPassword\" name=\"ftpPassword\" size=40 /></td></tr>");
document.write("<tr><td class=\"contentData\" colspan=2 align=center><int type=\"button\" onclick=\"redirectToFTP();\" value=\"Access FTP\" /></td></t");
document.write("</table>");
document.write("</form>");
}
function redirectToFTP(){
var username=escape(document.getElementById("ftpUsername").value);
var password=escape(document.getElementById("ftpPassword").value);
location.href = "ftp://" username ":" password "@XXX:80/"
}
</script>
<!--/Content-->
<!--Info-->
<table >
<tr>
<td >
<b>URL: </b><script type="censored");</script><br />
</td>
</tr>
</table>
<!--/Info-->
<!--/Contents-->
<!--Policy-->
<table class='policyTable'>
<tr>
<td class='policyHeading'>
<hr>
Company Acceptable Use Policy
</td>
</tr>
<tr>
<td class='policyData'>
This is an optional acceptable use disclaimer that appears on every pageYou may change the wording or remove this section entirely in index.html.
</td>
</tr>
</table>
<!--/Policy-->
<!--Foot-->
<table class='footTable'>
<tr>
<td class='helpDeskData' background='censored'>
For assistance, please contact your system administrator.
</td>
</tr>
<tr>
<td class='footData'>
generated <span id="time">2022-08-09 14:58:22</span> by McAfee Web Gatew
<br />
curl/7.60.0<br />
Node: censored<br />
Client IP: censored<br />
User: <br />
User-Groups: <br />
Authentication Method: <br />
Rule Set: Authentication with Kerberos and NTLM Fallback<br />
Rule: Perform Authentication<br />
</td>
</tr>
</table>
<!--/Foot-->
</td>
</tr>
</table>
</body>
<!--/Body-->
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "censored">
<html>
<!-- FileName: index.html
Language: [en]
-->
<!--Head-->
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<title>McAfee Web Gateway - Notification</title>
<script src="censored" type="text/vascript" ></script>
<link rel="stylesheet" href="/mwg-internal/de5fs23hu73ds/files/default/styleeet.css" />
</head>
<!--/Head-->
<!--Body-->
<body onl oad="swOnLoad();">
<table class='bodyTable'>
<tr>
<td class='bodyData' background='censored'>
<!--Logo-->
<table class='logoTable'>
<tr>
<td class='logoData'>
<a href='http://www.mcafee.com'>
<img src='censored'>a>
</td>
</tr>
</table>
<!--/Logo-->
<!--Contents-->
<!-- FileName: authenticationrequired.html
Language: [en]
-->
<!--Title-->
<table class='titleTable' background='/mwg-internal/de5fs23hu73ds/files/defaulimg/bg_navbar.jpg'>
<tr>
<td class='titleData'>
Authentication Required
</td>
</tr>
</table>
<!--/Title-->
<!--Content-->
<table >
<tr>
<td >
You must be authenticated to access this URL.
</td>
</tr>
</table>
<script language="javascript" type="text/javascript">
urlprotocol = "http";
statuscode=407;
if(statuscode==401 && urlprotocol == "ftp"){
document.write("<form name=\"ftpform\" method=\"get\" action=\"\">");
document.write("<table class=\"contentData\">");
document.write("<tr><td class=\"contentData\" colspan=2>Please enter youcredentials in the form below and click \"Access FTP\" button if your browser esn't present authentication prompt for FTP sites.</td></tr>");
document.write("<tr><td class=\"contentData\">Username:</td><td><input te=\"text\" id=\"ftpUsername\" name=\"ftpUsername\" size=40 /></td></tr>");
document.write("<tr><td class=\"contentData\">Password:</td><td><input te=\"password\" id=\"ftpPassword\" name=\"ftpPassword\" size=40 /></td></tr>");
document.write("<tr><td class=\"contentData\" colspan=2 align=center><int type=\"button\" onclick=\"redirectToFTP();\" value=\"Access FTP\" /></td></t");
document.write("</table>");
document.write("</form>");
}
function redirectToFTP(){
var username=escape(document.getElementById("ftpUsername").value);
var password=escape(document.getElementById("ftpPassword").value);
location.href = "ftp://" username ":" password "@YYY:80/"
}
</script>
<!--/Content-->
<!--Info-->
<table >
<tr>
<td >
<b>URL: </b><script type="text/javascript">break_line("http://setDownTim");</script><br />
</td>
</tr>
</table>
<!--/Info-->
<!--/Contents-->
<!--Policy-->
<table class='policyTable'>
<tr>
<td class='policyHeading'>
<hr>
Company Acceptable Use Policy
</td>
</tr>
<tr>
<td class='policyData'>
This is an optional acceptable use disclaimer that appears on every pageYou may change the wording or remove this section entirely in index.html.
</td>
</tr>
</table>
<!--/Policy-->
<!--Foot-->
<table class='footTable'>
<tr>
<td class='helpDeskData' background='/mwg-internal/de5fs23hu73ds/files/deflt/img/bg_navbar.jpg'>
For assistance, please contact your system administrator.
</td>
</tr>
<tr>
<td class='footData'>
generated <span id="time">2022-08-09 14:58:22</span> by McAfee Web Gatew
<br />
curl/7.60.0<br />
Node:censored<br />
Client IP: censored<br />
User: <br />
User-Groups: <br />
Authentication Method: <br />
Rule Set: Authentication with Kerberos and NTLM Fallback<br />
Rule: Perform Authentication<br />
</td>
</tr>
</table>
<!--/Foot-->
</td>
</tr>
</table>
</body>
<!--/Body-->
</html>
{"title": "You need to be authenticated to use the REST API.", "status": 401}
I needed to cut that part because I was over the characterlimit for the post...
I think that my error is not that hard to solve but I dont know enough about bash to search for the right things so please get easy on me. I used bash the first time in june this year so try to keep the answers a bit simpler than to an usual bash user please, thank you in advance for your help and consideration.
CodePudding user response:
Like I guessed my problem was a minor one... only thing wrong was the ":" in my headers, just had to exchange them for "=".
Well got a new problem but I doubt that you guys can help me when I am not allowed to share more information about our server and applications.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
afer that message I did the same thing in the body like in my header but that didnt do the thing.
CodePudding user response:
Here's a rewrite of your script in bash
using curl
, because it'll be easier to discuss against an example rather than an abstract in comments.
This, at least to my eyes, does exactly what your Powershell script is doing.
#!/bin/bash
url="https://YOUR-URL"
username="XXX"
password="YYY"
hostname="ZZZ"
# first Invoke-RestMethod, which is a GET with JSON...
# -1 means "use TLS1 or newer"
# -XGET is required here to force it to be a request
# that uses GET with a body, since curl would default to POST
# if '-d' is specified
# -w "%{http_code}\n" means output the http code
# if you want to suppress all other output and only
# get the http code output, specify these additional options:
# -o /dev/null -s
curl $url -1 -XGET \
-H "Accept: application/json" \
-H "Authorization: Bearer $username $password" \
-w "%{http_code}\n" \
-d "{ \"host_name\": \"$hostname\" }"
# Downtime Invoke-RestMethod
minutes_diff=30
start_diff=120
# because in your original, you do (now - 2 hours) $minutes_diff
# so it's just now -(120 - $minutes_diff) minutes
end_diff=$(( 120 - $minutes_diff ))
# This was based on you using the .NET -u specifier which is
# intended for use with UTC DateTime objects
# I don't know if you actually want your timestamps derived
# from UTC time, which is what "-u" does for the date command
start_time=$(date -u -d "$start_diff minutes ago" "%Y-%m-%d %H:%M:%SZ")
end_time=$(date -u -d "$end_diff minutes ago" "%Y-%m-%d %H:%M:%SZ")
# you didn't have an EXTRAINFO in your original script
# so I left it out
comment="$minutes_diff min Restart Downtime"
# The -d @- <<-JSON uses a heredoc so I can
# more nicely express the JSON you send
curl $url -1 \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer $username $password" \
-w "%{http_code}\n" \
-d @- <<-JSON
{
"start_time": "$start_time",
"end_time": "$end_time",
"comment": "$comment",
"host_name": "$hostname",
"downtime_type": "host"
}
JSON