diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1c1177de54160b81ee9ae9bca9e5a42d62bffc5a --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# REST API CLIENT + +This is a bash solution to script REST API calls. + +The specialties of this component are + +* It was build to simplify http calls and handle http response for scripts +* After making a request the response stays is in memory. There is no output to any file to grep something or to cleanup after usage. +* Its functions feel a bit like class methods, i.e. http.getResponse to get the response body or http.getResponseHeader for the Http response header +* This component wraps curl - ist supports any http method +* works with anonymous requests and Basic Authentication +* The response can be stored ... and reimported later. After import you can use the http.get* functions to fetch results from the former request. +* Caching support for GET requests with a given TTL: if you repeat a request to the same url and ttl was not reached yet then you continue with the cached result + +Source: https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client + +License: GNU GPL 3 + +## Requirements + +* Bash as shell (runs on Linux - or with Cygwin or other Bash implementations on MS Windows too.) +* Curl must be in the path +* optional: sha1sum (for export function with autogenerated filenames only) + +--- + +[Installation](./docs/10_Installation.md) | [Usage](./docs/20_Usage.md) \ No newline at end of file diff --git a/docs/10_Installation.md b/docs/10_Installation.md new file mode 100644 index 0000000000000000000000000000000000000000..1e67cab7fe0ba7a37b6c9299a00e8fc7a161bb3b --- /dev/null +++ b/docs/10_Installation.md @@ -0,0 +1,19 @@ +# Download + + +Download the archive i.e. as zip: + +https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client/-/archive/master/bash-rest-api-client-master.zip + +(see other formats at the download button on https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client) + +# OR: Git clone + +```sh +git clone https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client.git +``` + +# Copy somewhere + +Copy the file `rest-api-client.sh` anywhere you want. +If you need it in a single script then copy it to its directory. If you need it more often then copy it to a folter of your PATH environment. diff --git a/readme.md b/docs/20_Usage.md similarity index 72% rename from readme.md rename to docs/20_Usage.md index eed17a790d9bb5decc867db97645cc13fee81dc7..591344e563bf463fa7b67e9be9ad8bde33bc4fc8 100644 --- a/readme.md +++ b/docs/20_Usage.md @@ -1,56 +1,13 @@ -# REST API CLIENT # - -This is a bash solution to script REST API calls. - -The specialties of this component are - -* It was build to simplify http calls and handle http response for scripts -* After making a request the response stays is in memory. There is no output to any file to grep something or to cleanup after usage. -* Its functions feel a bit like class methods, i.e. http.getResponse to get the response body or http.getResponseHeader for the Http response header -* This component wraps curl - ist supports any http method -* works with anonymous requests and Basic Authentication -* The response can be stored ... and reimported later. After import you can use the http.get* functions to fetch results from the former request. -* Caching support for GET requests with a given TTL - - -Source: https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client - -License: GNU GPL 3 - - -## Requirements ## - -* Bash as shell (runs on Linux - or with Cygwin or other Bash implementations on MS Windows too.) -* Curl must be in the path -* optional: sha1sum (for export function with autogenerated filenames only) - - -## Installation ## - -**Download** the archive i.e. as zip: - -https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client/-/archive/master/bash-rest-api-client-master.zip - -(see other formats at the download button on https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client) - -or **Git clone** - -``` -$ git clone https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client.git -``` - -Copy the *rest-api-client.sh* anywhere you want. - - -## Usage ## +# Step 1: source the script You must source the rest-api-client.sh. Then its functions are usable in the current process. The "methods" start with "http" dot "[method]". -You should start with *http.help* to get an overwiew. +# Step 2: Use http.* functions +You should start with *http.help* to get an overwiew. -``` +```sh # # step one: source the shell script # diff --git a/docs/30_Examples.md b/docs/30_Examples.md new file mode 100644 index 0000000000000000000000000000000000000000..c3a92f74cda6e6e83a4695481d864882ae46d599 --- /dev/null +++ b/docs/30_Examples.md @@ -0,0 +1,112 @@ +# Preparation + +A required step is sourcing the script to make the http.* function available in the current shell. + +```sh +# --- source script +> . ./rest-api-client.sh +``` + +Then you can follow the examples. + +# A first example + +```sh +# --- init ... to flush anything of a request that was made before +> http.init + +# --- make a GET request ... +> http.makeRequest GET http://www.iml.unibe.ch +# OR "http.makeRequest [url]" ... GET is the default + +# --- get the result +> http.getStatuscode +301 + +> http.getStatus +Redirect + +# --- view the http response header +> http.getResponseHeader +HTTP/1.1 301 Moved Permanently +Date: Tue, 11 Jan 2022 12:26:37 GMT +Server: Apache +Location: https://www.iml.unibe.ch/ +Content-Length: 233 +Connection: close +Content-Type: text/html; charset=iso-8859-1 + +# --- view curl data +> http.getResponseData +http_code:301 +http_connect:000 +local_ip:172.30.158.65 +local_port:58512 +num_connects:1 +num_redirects:0 +redirect_url:https://www.iml.unibe.ch/ +remote_ip:130.92.30.80 +remote_port:80 +size_download:233 +size_header:209 +size_request:139 +size_upload:0 +speed_download:3405 +speed_upload:0 +ssl_verify_result:0 +time_appconnect:0.000000 +time_connect:0.049925 +time_namelookup:0.024735 +time_pretransfer:0.050054 +time_redirect:0.000000 +time_starttransfer:0.068274 +time_total:0.068411 +url_effective:http://www.iml.unibe.ch/ + +``` + +# Icinga API + +In that example we have a config for an api access with url, user and password. +The docs url is not required for functionality. It will be shown on errors. + +Imagine, to deploy such a config with Ansible/ Puppet/ on all hosts. + +```sh +# --- data in a config file that is sourced by your script: +RestApiBaseUrl="https://icinga-endpoint.example.com:5665/v1/" +RestApiUser="icingaapi" +RestApiPassword="password-of-Icinga-Api-User" +RestApiDocs="https://icinga.com/docs/icinga2/latest/doc/12-icinga2-api/" +``` + +And now let's access the Icinga API... + +```sh +myHost=( hostname -f ) + +# --- init: +http.init +http.setAuth "${RestApiUser}:${RestApiPassword}" +http.setBaseUrl "${RestApiBaseUrl}" +http.setDocs "${RestApiDocs}" + +# --- check if my host exists in the monitoring +# Because we set a base url we can operate with the part behind it +http.makeRequest GET "objects/hosts/${myHost}" + +# set return code of GET action ... $? is 0 on success (2xx status code) +http.isOk >/dev/null + +# --- show a result +if [ $? -ne 0 ]; then + http.getResponse + if [ "`http.getStatuscode`" = "000" ]; then + echo "ERROR: Unable to reach the Icinga node. Stopping script current monitoring actions." + exit 1 + fi + echo "ERROR: host object for ${myHost} is not available on Icinga service (yet) - Status: `http.getStatuscode`" + exit 1 +fi +echo "OK, ${myHost} was found." +``` diff --git a/docs/_index.md b/docs/_index.md new file mode 100644 index 0000000000000000000000000000000000000000..5541390c9c284956728423f483189877201c6c62 --- /dev/null +++ b/docs/_index.md @@ -0,0 +1,23 @@ +# Description + +This is a bash solution to script REST API calls. + +The specialties of this component are + +* It was build to simplify http calls and handle http response for scripts +* After making a request the response stays is in memory. There is no output to any file to grep something or to cleanup after usage. +* Its functions feel a bit like class methods, i.e. http.getResponse to get the response body or http.getResponseHeader for the Http response header +* This component wraps curl - ist supports any http method +* works with anonymous requests and Basic Authentication +* The response can be stored ... and reimported later. After import you can use the http.get* functions to fetch results from the former request. +* Caching support for GET requests with a given TTL: if you repeat a request to the same url and ttl was not reached yet then you continue with the cached result + +Source: https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client + +License: GNU GPL 3 + +# Requirements + +* Bash as shell (runs on Linux - or with Cygwin or other Bash implementations on MS Windows too.) +* Curl must be in the path +* optional: sha1sum (for export function with autogenerated filenames only) diff --git a/docs/config.json b/docs/config.json new file mode 100644 index 0000000000000000000000000000000000000000..d66950af28ba32447ec6cc8af06201ec1dbb3f33 --- /dev/null +++ b/docs/config.json @@ -0,0 +1,20 @@ +{ + "title": "Bash: Rest-Api-Client", + "author": "Axel Hahn; Institute for Medical Education; University of Bern", + "ignore": { + "files": ["30_PHP-client/Plugins/Checks/_skeleton.md"], + "folders": ["99_Not_Ready"] + }, + "html": { + "auto_landing": false, + "auto_toc": true, + "date_modified": false, + "jump_buttons": true, + "edit_on_github_": "iml-it/appmonitor/tree/master/docs", + "links": { + "GitHub Repo": "https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client" + }, + "theme": "daux-blue", + "search": true + } +} \ No newline at end of file diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000000000000000000000000000000000000..aa0563aa4cbe6cf5b2ac363d95eaf12b0e81c96f --- /dev/null +++ b/docs/style.css @@ -0,0 +1,178 @@ +/* + + patch css elements of daux.io blue theme + +*/ + + +/* ---------- vars ---------- */ + +:root{ + + /* background colors */ + --bg:none; + --bg-body: #fff; + --bg-navlinkactive:#f4f4f4; + --bg-navlinkactive: linear-gradient(-90deg,rgba(0,0,0,0), rgba(40,60,80,0.05) 30%); + --bg-pre:linear-gradient(-4deg, #f0f0f0, #fefefe,#f0f0f0); + --bg-toc: #fff; + + /* foreground colors */ + --color: #234; + --navlinkactive:#f33; + --title: #aaa; + + --link:#12a; + --toclink:rgba(40,60,80,0.8); + --pagerlink:rgba(40,60,80,0.8); + + --h1: rgba(40,60,80,0.8); + --h1-bottom: 1px solid rgba(40,60,80,0.1); + --h2: rgba(40,60,80,0.5); + --h3: rgba(40,60,80,0.3); + +} + +/* ---------- tags ---------- */ + +body, *{color: var(--color); } +body{background: var(--bg-body);} + + +a{color: var(--link);} +a:hover{opacity: 0.7;} + +h1>a{ color:var(--title);} +_h1:nth-child(1){position: fixed; background: var(--bg); box-shadow: 0 0 1em #ccc; padding: 0 1em} +h1:nth-child(1)>a{ color:var(--navlinkactive); } + +.s-content h1{color: var(--h1); font-size: 200%; font-weight:bold; margin-top: 2em; border-bottom: var(--h1-bottom);} +.s-content h2{color: var(--h2); font-size: 160%; } +.s-content h3{color: var(--h3); font-size: 140%; } +.s-content h4{margin: 0; font-size: 100%; text-align: center; background-color: rgba(0,0,0,0.05);padding: 0.3em;} + +.s-content pre{ + background: var(--bg-pre); + border: 4px solid #fff; + box-shadow: 0 0 2em #eee; +} + +/* ---------- classes ---------- */ + +.required{color:#a42;} +.optional{color:#888;} + + +/* ----- top left */ +.Brand, +.Columns__left { + background: var(--bg); + border-right: 0px solid #e7e7e9; + color: var(--color); +} +.Brand{font-size: 200%; + background_: linear-gradient(-10deg,#fff 50%, #ddd); + background: var(--bg); +} +.Columns__right__content { + background: var(--bg); +} + +/* ----- Navi left */ + +.Nav a:hover{ + background: none; + color: var(--navlinkactive) !important; +} + +.Nav__item--active { + border-right_: 0.3em solid var(--navlinkactive); +} +.Nav__item--active > a{ + background: var(--bg-navlinkactive); + color: var(--navlinkactive); +} +.Nav .Nav .Nav__item--active a { + color: var(--navlinkactive); +} +.Nav .Nav .Nav__item a { + opacity: 1; +} +.Nav__item--open > a { + background-color: var(--bg); +} + +.Nav a[href*="__Welcome"]{ + background: url("/icons/house.png") no-repeat 10px 4px ; + padding-left: 40px; +} +.Nav a[href*="__How_does_it_work"]{ + background: url("/icons/light-bulb.png") no-repeat 10px 4px ; + padding-left: 40px; +} + + + + +/* ---------- classes ---------- */ + +/* FIX smaller fnt size in tables */ +.s-content table { + font-size: 1em; +} + + +/* TOC */ +@media(min-width:1700px){ + .TableOfContentsContainer{ + position: fixed; + right: 2em; + top: 1em; + } +} + +.TableOfContentsContainer{ + border-top-left-radius: 1em; + background-color: var(--bg-toc); + border-left: 2px solid rgba(0,0,0,0.05); + padding: 0em; +} +.TableOfContentsContainer__content { + + border: none; + font-size: 0.5em; + +} +ul.TableOfContents ul{ + list-style-type: none; + padding-left: 1em; +} +.TableOfContentsContainer a{ color:var(--toclink);} + +.TableOfContentsContainer__content > .TableOfContents > li + li { + border-top: none; +} +.TableOfContentsContainer__content > .TableOfContents > li { + border-bottom: 1px dashed #ddd; +} + +/* pager - prev .. next */ +.s-content{ + margin-bottom: 6em; +} +.Pager{ + __border-top: 1px dashed #aaa; + margin: 0; padding: 1em; + box-shadow: 0 -0.5em 1em #f8f8f8; +} +.Pager li a{ + color:var(--pagerlink); + border: 2px solid #f8f8f8; + box-shadow: 0.3em 0.3em 0.5em #eee; + transition: all ease-in-out 0.3s; +} + +.Pager li a:hover{ + border: 2px solid #fff; + box-shadow: 0.1em 0.1em 0.2em #eee; +} \ No newline at end of file