# Deregister client automatically \<possible solution\>

**URL:** <https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309>\
**Category:** Sensu Classic (EOL)\
**Created:** [November 14, 2014, 3:40pm UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309 "2014-11-14T15:40:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![matty\_jones](https://avatars.discourse-cdn.com/v4/letter/m/c89c15/32.png) [@matty\_jones](https://discourse.sensu.io/u/matty_jones)\
**Post date:** [November 14, 2014, 3:40pm UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309/1 "2014-11-14T15:40:26Z")

</div>

Background/Problem:

I use vagrant a lot for testing so when I spin up a vagrant box, using Chef, it will register itself with my sensu environment. When I kill the vagrant box I need to go to the dashboard and remove the client, if I remember too. At the moment I don’t want to expose the sensu-api beyond the api server itself, yet I want a way to deregister a client from sensu automatically. I also don’t want every developer and user out there to have the ability to resolve events either or issue api commands at will.

Proposed Solution:

An init script on the client side runs when a graceful shutdown is performed, this script calls a ruby plugin that drops a check-result onto port 3030 of the local machine for the client to deliver to the server. The “output” of this result can be any api command, in this case I set the output to delete, example:

‘{ “name”: “api\_call”, “output”: “delete”, “process”: “init”, “user”: “root”, “handler”: “sensu-api-handler”}’

A handler on the server is set as a pipe and sends the check-result to an “api-handler”. This handler then evaluates the output string to decide what to do. In this case it sees delete. The handler then, using the api, creates a stash containing the following:

{“path”: “api\_call”/

“content”: {

node:

user: default is sensu

process: default is sensu

api\_cmd: “delete”

timestamp: Time.now

}}

Forgive any syntax errors, thats what linters are for. Then, using the api as well, a delete command is issued to the api-server and removes that client from the dashboard.

This stash is created so that with modification, the handlers check here for a delete value and if so drop the check-result as the machine will be going down cleanly soon.

For cleanup, I have a check that runs every 60 seconds and removes stashes with a value of delete, this prevents Sensu from dropping valid results do to a stash.

I am aware that there is a way to expire the stashes automatically, I just haven’t gotten that far yet. In a perfect world I wouldn’t need to do this. The client, upon graceful shutdown, would issue an api delete command and remove itself, at some point I will look at that. Also, it would be nice if the client was able to do some of the above steps naturally. Possibly by picking up a key/value pair in a check result and knowing that this is an api command.

I understand there is/would be some duplicate effort involved here. The main thought behind this is to leverage the check-result Q to deliver api commands to the api server, thereby exposing one less machine, or distributing one less key/credentials to the environment. A method such as this may also be a way to control or mange in a small capacity appliances by having a dedicated sensu-client be responsible for accepting traps from a group of appliances and issuing api commands on behalf of the appliance.

Just figured I would throw this out there

---

<div class="post-metadata">

**Author:** ![Kyle\_Anderson](https://avatars.discourse-cdn.com/v4/letter/k/e5b9ba/32.png) [@Kyle\_Anderson](https://discourse.sensu.io/u/Kyle_Anderson)\
**Post date:** [November 15, 2014, 4:13am UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309/2 "2014-11-15T04:13:22Z")

</div>

Why not have the sensu-api-handler just remove the client immediately,  
and skip the stash part?  
It could be a simple bash script that just runs sensu-cli client  
delete $cilent\_name

Also, client side you don't need any fancy ruby script, just bash is  
fine if you want:  
echo '{ "name": "api\_call", "output": "delete", "process": "init",  
"user": "root", "handler": "sensu-api-handler"}' \>  
/dev/tcp/localhost/3030

You will need a non-zero status code to get your handler to pick up on it.

Just make sure your init scripts are ordered correctly, I have  
something similar in production and getting the shutdown sequence  
ordered correctly across different distros and init systems is hard.  
My thing does a sensu-cli client delete on shutdown, level 0 (I  
distribute credentials to the clients), and I add a 5 minute silence  
stash on reboot (6).

> **···**
>
> On Fri, Nov 14, 2014 at 7:40 AM, matty jones \<urlugal@gmail.com\> wrote:
> 
> > Background/Problem:
> > 
> > I use vagrant a lot for testing so when I spin up a vagrant box, using Chef,  
> > it will register itself with my sensu environment. When I kill the vagrant  
> > box I need to go to the dashboard and remove the client, if I remember too.  
> > At the moment I don't want to expose the sensu-api beyond the api server  
> > itself, yet I want a way to deregister a client from sensu automatically. I  
> > also don't want every developer and user out there to have the ability to  
> > resolve events either or issue api commands at will.
> > 
> > Proposed Solution:
> > 
> > An init script on the client side runs when a graceful shutdown is  
> > performed, this script calls a ruby plugin that drops a check-result onto  
> > port 3030 of the local machine for the client to deliver to the server. The  
> > "output" of this result can be any api command, in this case I set the  
> > output to delete, example:
> > 
> > '{ "name": "api\_call", "output": "delete", "process": "init", "user":  
> > "root", "handler": "sensu-api-handler"}'
> > 
> > A handler on the server is set as a pipe and sends the check-result to an  
> > "api-handler". This handler then evaluates the output string to decide what  
> > to do. In this case it sees delete. The handler then, using the api,  
> > creates a stash containing the following:
> > 
> > {"path": "api\_call"/\<sensu-client\>  
> > "content": {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node: \<sensu-client\>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user: \<user making the call\> default is sensu  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process: \<process making the call\> default is sensu  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;api\_cmd: "delete"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timestamp: Time.now  
> > }}
> > 
> > Forgive any syntax errors, thats what linters are for. Then, using the api  
> > as well, a delete command is issued to the api-server and removes that  
> > client from the dashboard.
> > 
> > This stash is created so that with modification, the handlers check here for  
> > a delete value and if so drop the check-result as the machine will be going  
> > down cleanly soon.
> > 
> > For cleanup, I have a check that runs every 60 seconds and removes stashes  
> > with a value of delete, this prevents Sensu from dropping valid results do  
> > to a stash.
> > 
> > I am aware that there is a way to expire the stashes automatically, I just  
> > haven't gotten that far yet. In a perfect world I wouldn't need to do this.  
> > The client, upon graceful shutdown, would issue an api delete command and  
> > remove itself, at some point I will look at that. Also, it would be nice if  
> > the client was able to do some of the above steps naturally. Possibly by  
> > picking up a key/value pair in a check result and knowing that this is an  
> > api command.
> > 
> > I understand there is/would be some duplicate effort involved here. The  
> > main thought behind this is to leverage the check-result Q to deliver api  
> > commands to the api server, thereby exposing one less machine, or  
> > distributing one less key/credentials to the environment. A method such as  
> > this may also be a way to control or mange in a small capacity appliances by  
> > having a dedicated sensu-client be responsible for accepting traps from a  
> > group of appliances and issuing api commands on behalf of the appliance.
> > 
> > Just figured I would throw this out there

---

<div class="post-metadata">

**Author:** ![Matt\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/258eb7/32.png) [@Matt\_Jones](https://discourse.sensu.io/u/Matt_Jones)\
**Post date:** [November 15, 2014, 4:28am UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309/3 "2014-11-15T04:28:30Z")

</div>

> Why not have the sensu-api-handler just remove the client immediately,  
> and skip the stash part?

The stash part is necessary to avoid a race condition where a keep alive  
comes in after the deregister has been sent.

> It could be a simple bash script that just runs sensu-cli client  
> delete $cilent\_name
> 
> The sensu-cli depends upon the sensu-api, to my understanding of the code

it is simply a wrapper, and in the case of my environment, the sensu-api is  
not exposed beyond the sensu server. If you mean on the server side, I  
prefer Ruby just to keep things all the same language, it also makes it  
simplier, for my environment anyway, to write tests for and manage.

> Also, client side you don't need any fancy ruby script, just bash is  
> fine if you want:  
> echo '{ "name": "api\_call", "output": "delete", "process": "init",  
> "user": "root", "handler": "sensu-api-handler"}' \>  
> /dev/tcp/localhost/3030

I don't want to do anything with the init script but call a Ruby script,  
makes it easier to template with Chef. I want the power/flexibility of  
Ruby as well, who knows what I will want to do later on with this script so  
I want a separate script to handle the json generation.. At some point in  
time the client side will be able to handle any api calls, so I wrote and  
designed it to account for this. I don't believe in writing one-offs it I  
can extrapolate the code out to something useful but still retain a sense  
of scope I will. The delete call was the one I needed right away so that  
is what I have been testing with the last few days.

> You will need a non-zero status code to get your handler to pick up on it.

> Just make sure your init scripts are ordered correctly, I have  
> something similar in production and getting the shutdown sequence  
> ordered correctly across different distros and init systems is hard.  
> My thing does a sensu-cli client delete on shutdown, level 0 (I  
> distribute credentials to the clients), and I add a 5 minute silence  
> stash on reboot (6).
> 
> The default client shutdown script is at 74 I believe, I set this script

to 70 but I am still going to create the stash as I don't like being nearly  
certain, or leaving things to chance such as network latency or whatnot. I  
want it to be absolute, and the only two ways in my mind to do that were to  
create a delete stash or to modify the client to do this itself as a last  
dying act (next on my list of things to not get done this year).

Thanks for the input

> **···**
>
> On Fri, Nov 14, 2014 at 11:13 PM, Kyle Anderson \<kyle@xkyle.com\> wrote:
> 
> > On Fri, Nov 14, 2014 at 7:40 AM, matty jones \<urlugal@gmail.com\> wrote:  
> > \> Background/Problem:  
> > \>  
> > \> I use vagrant a lot for testing so when I spin up a vagrant box, using  
> > Chef,  
> > \> it will register itself with my sensu environment. When I kill the  
> > vagrant  
> > \> box I need to go to the dashboard and remove the client, if I remember  
> > too.  
> > \> At the moment I don't want to expose the sensu-api beyond the api server  
> > \> itself, yet I want a way to deregister a client from sensu  
> > automatically. I  
> > \> also don't want every developer and user out there to have the ability to  
> > \> resolve events either or issue api commands at will.  
> > \>  
> > \> Proposed Solution:  
> > \>  
> > \> An init script on the client side runs when a graceful shutdown is  
> > \> performed, this script calls a ruby plugin that drops a check-result onto  
> > \> port 3030 of the local machine for the client to deliver to the server.  
> > The  
> > \> "output" of this result can be any api command, in this case I set the  
> > \> output to delete, example:  
> > \>  
> > \> '{ "name": "api\_call", "output": "delete", "process": "init", "user":  
> > \> "root", "handler": "sensu-api-handler"}'  
> > \>  
> > \> A handler on the server is set as a pipe and sends the check-result to an  
> > \> "api-handler". This handler then evaluates the output string to decide  
> > what  
> > \> to do. In this case it sees delete. The handler then, using the api,  
> > \> creates a stash containing the following:  
> > \>  
> > \> {"path": "api\_call"/\<sensu-client\>  
> > \> "content": {  
> > \> node: \<sensu-client\>  
> > \> user: \<user making the call\> default is sensu  
> > \> process: \<process making the call\> default is sensu  
> > \> api\_cmd: "delete"  
> > \> timestamp: Time.now  
> > \> }}  
> > \>  
> > \> Forgive any syntax errors, thats what linters are for. Then, using the  
> > api  
> > \> as well, a delete command is issued to the api-server and removes that  
> > \> client from the dashboard.  
> > \>  
> > \> This stash is created so that with modification, the handlers check here  
> > for  
> > \> a delete value and if so drop the check-result as the machine will be  
> > going  
> > \> down cleanly soon.  
> > \>  
> > \> For cleanup, I have a check that runs every 60 seconds and removes  
> > stashes  
> > \> with a value of delete, this prevents Sensu from dropping valid results  
> > do  
> > \> to a stash.  
> > \>  
> > \> I am aware that there is a way to expire the stashes automatically, I  
> > just  
> > \> haven't gotten that far yet. In a perfect world I wouldn't need to do  
> > this.  
> > \> The client, upon graceful shutdown, would issue an api delete command and  
> > \> remove itself, at some point I will look at that. Also, it would be  
> > nice if  
> > \> the client was able to do some of the above steps naturally. Possibly by  
> > \> picking up a key/value pair in a check result and knowing that this is an  
> > \> api command.  
> > \>  
> > \> I understand there is/would be some duplicate effort involved here. The  
> > \> main thought behind this is to leverage the check-result Q to deliver api  
> > \> commands to the api server, thereby exposing one less machine, or  
> > \> distributing one less key/credentials to the environment. A method such  
> > as  
> > \> this may also be a way to control or mange in a small capacity  
> > appliances by  
> > \> having a dedicated sensu-client be responsible for accepting traps from a  
> > \> group of appliances and issuing api commands on behalf of the appliance.  
> > \>  
> > \> Just figured I would throw this out there

---

<div class="post-metadata">

**Author:** ![Aiman\_Parvaiz](https://avatars.discourse-cdn.com/v4/letter/a/f19dbf/32.png) [@Aiman\_Parvaiz](https://discourse.sensu.io/u/Aiman_Parvaiz)\
**Post date:** [July 22, 2015, 2:51am UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309/4 "2015-07-22T02:51:24Z")

</div>

Matt, did you figure out how to go about this. I am also looking for something similar.

Thanks

> **···**
>
> On Friday, November 14, 2014 at 8:28:31 PM UTC-8, Matt Jones wrote:
> 
> > On Fri, Nov 14, 2014 at 11:13 PM, Kyle Anderson [ky...@xkyle.com](mailto:ky...@xkyle.com) wrote:
> > 
> > > Why not have the sensu-api-handler just remove the client immediately,
> > > 
> > > and skip the stash part?
> 
> > The stash part is necessary to avoid a race condition where a keep alive comes in after the deregister has been sent.
> 
> > > It could be a simple bash script that just runs sensu-cli client
> > > 
> > > delete $cilent\_name
> > 
> > The sensu-cli depends upon the sensu-api, to my understanding of the code it is simply a wrapper, and in the case of my environment, the sensu-api is not exposed beyond the sensu server. If you mean on the server side, I prefer Ruby just to keep things all the same language, it also makes it simplier, for my environment anyway, to write tests for and manage.
> 
> > > Also, client side you don’t need any fancy ruby script, just bash is
> > > 
> > > fine if you want:
> > > 
> > > echo '{ “name”: “api\_call”, “output”: “delete”, “process”: “init”,
> > > 
> > > “user”: “root”, “handler”: “sensu-api-handler”}’ \>
> > > 
> > > /dev/tcp/localhost/3030
> 
> > I don’t want to do anything with the init script but call a Ruby script, makes it easier to template with Chef. I want the power/flexibility of Ruby as well, who knows what I will want to do later on with this script so I want a separate script to handle the json generation… At some point in time the client side will be able to handle any api calls, so I wrote and designed it to account for this. I don’t believe in writing one-offs it I can extrapolate the code out to something useful but still retain a sense of scope I will. The delete call was the one I needed right away so that is what I have been testing with the last few days.
> 
> > > You will need a non-zero status code to get your handler to pick up on it.
> > > 
> > > Just make sure your init scripts are ordered correctly, I have
> > > 
> > > something similar in production and getting the shutdown sequence
> > > 
> > > ordered correctly across different distros and init systems is hard.
> > > 
> > > My thing does a sensu-cli client delete on shutdown, level 0 (I
> > > 
> > > distribute credentials to the clients), and I add a 5 minute silence
> > > 
> > > stash on reboot (6).
> 
> > The default client shutdown script is at 74 I believe, I set this script to 70 but I am still going to create the stash as I don’t like being nearly certain, or leaving things to chance such as network latency or whatnot. I want it to be absolute, and the only two ways in my mind to do that were to create a delete stash or to modify the client to do this itself as a last dying act (next on my list of things to not get done this year).
> 
> > 
> 
> > Thanks for the input
> 
> > > On Fri, Nov 14, 2014 at 7:40 AM, matty jones [url...@gmail.com](mailto:url...@gmail.com) wrote:
> > > 
> > > > Background/Problem:
> > > 
> > > > 
> > > 
> > > > I use vagrant a lot for testing so when I spin up a vagrant box, using Chef,
> > > 
> > > > it will register itself with my sensu environment. When I kill the vagrant
> > > 
> > > > box I need to go to the dashboard and remove the client, if I remember too.
> > > 
> > > > At the moment I don’t want to expose the sensu-api beyond the api server
> > > 
> > > > itself, yet I want a way to deregister a client from sensu automatically. I
> > > 
> > > > also don’t want every developer and user out there to have the ability to
> > > 
> > > > resolve events either or issue api commands at will.
> > > 
> > > > 
> > > 
> > > > Proposed Solution:
> > > 
> > > > 
> > > 
> > > > An init script on the client side runs when a graceful shutdown is
> > > 
> > > > performed, this script calls a ruby plugin that drops a check-result onto
> > > 
> > > > port 3030 of the local machine for the client to deliver to the server. The
> > > 
> > > > “output” of this result can be any api command, in this case I set the
> > > 
> > > > output to delete, example:
> > > 
> > > > 
> > > 
> > > > '{ “name”: “api\_call”, “output”: “delete”, “process”: “init”, “user”:
> > > 
> > > > “root”, “handler”: “sensu-api-handler”}’
> > > 
> > > > 
> > > 
> > > > A handler on the server is set as a pipe and sends the check-result to an
> > > 
> > > > “api-handler”. This handler then evaluates the output string to decide what
> > > 
> > > > to do. In this case it sees delete. The handler then, using the api,
> > > 
> > > > creates a stash containing the following:
> > > 
> > > > 
> > > 
> > > > {“path”: “api\_call”/
> > > 
> > > > “content”: {
> > > 
> > > > ```
> > > > node: <sensu-client>
> > > > 
> > > > ```
> > > 
> > > > ```
> > > > user: <user making the call> default is sensu
> > > > 
> > > > ```
> > > 
> > > > ```
> > > > process: <process making the call> default is sensu
> > > > 
> > > > ```
> > > 
> > > > ```
> > > > api_cmd: "delete"
> > > > 
> > > > ```
> > > 
> > > > ```
> > > > timestamp: Time.now
> > > > 
> > > > ```
> > > 
> > > > }}
> > > 
> > > > 
> > > 
> > > > Forgive any syntax errors, thats what linters are for. Then, using the api
> > > 
> > > > as well, a delete command is issued to the api-server and removes that
> > > 
> > > > client from the dashboard.
> > > 
> > > > 
> > > 
> > > > This stash is created so that with modification, the handlers check here for
> > > 
> > > > a delete value and if so drop the check-result as the machine will be going
> > > 
> > > > down cleanly soon.
> > > 
> > > > 
> > > 
> > > > For cleanup, I have a check that runs every 60 seconds and removes stashes
> > > 
> > > > with a value of delete, this prevents Sensu from dropping valid results do
> > > 
> > > > to a stash.
> > > 
> > > > 
> > > 
> > > > I am aware that there is a way to expire the stashes automatically, I just
> > > 
> > > > haven’t gotten that far yet. In a perfect world I wouldn’t need to do this.
> > > 
> > > > The client, upon graceful shutdown, would issue an api delete command and
> > > 
> > > > remove itself, at some point I will look at that. Also, it would be nice if
> > > 
> > > > the client was able to do some of the above steps naturally. Possibly by
> > > 
> > > > picking up a key/value pair in a check result and knowing that this is an
> > > 
> > > > api command.
> > > 
> > > > 
> > > 
> > > > I understand there is/would be some duplicate effort involved here. The
> > > 
> > > > main thought behind this is to leverage the check-result Q to deliver api
> > > 
> > > > commands to the api server, thereby exposing one less machine, or
> > > 
> > > > distributing one less key/credentials to the environment. A method such as
> > > 
> > > > this may also be a way to control or mange in a small capacity appliances by
> > > 
> > > > having a dedicated sensu-client be responsible for accepting traps from a
> > > 
> > > > group of appliances and issuing api commands on behalf of the appliance.
> > > 
> > > > 
> > > 
> > > > Just figured I would throw this out there
> 
> >

---

<div class="post-metadata">

**Author:** ![Philipp\_H](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.sensu.io/philipp_h/32/539_2.png) [@Philipp\_H](https://discourse.sensu.io/u/Philipp_H)\
**Post date:** [July 22, 2015, 6:27pm UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309/5 "2015-07-22T18:27:32Z")

</div>

It looks like sensu client will get native deregister support in the future. The roadmap scheduled it to 0.21.

---

<div class="post-metadata">

**Author:** ![Joao\_Carlos](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@Joao\_Carlos](https://discourse.sensu.io/u/Joao_Carlos)\
**Post date:** [July 22, 2015, 8:13pm UTC](https://discourse.sensu.io/t/deregister-client-automatically-possible-solution/309/6 "2015-07-22T20:13:33Z")

</div>

GREAT!!!

> **···**
>
> Em quarta-feira, 22 de julho de 2015 15:27:32 UTC-3, Philipp H escreveu:
> 
> > It looks like sensu client will get native deregister support in the future. The roadmap scheduled it to 0.21.
