Compare commits
21 Commits
4b43bd1338
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a4c42f9c0 | |||
| 99529579fe | |||
| 49f6a3d26a | |||
| 60598566d0 | |||
| 15f8793e2f | |||
| d574902919 | |||
| a08de8a553 | |||
| 0b2bba5d77 | |||
| 398e16e724 | |||
| e93346f646 | |||
| 3e3725ec22 | |||
| 9fa2c02c9d | |||
| cbf41e0842 | |||
| 44b1bcb634 | |||
| ae72957a1a | |||
| 2a530681df | |||
| 7256763c20 | |||
| 54ddafd0fc | |||
| baeab6daf2 | |||
| 5818349d91 | |||
| b0723ae708 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,6 +2,7 @@
|
|||||||
.envrc
|
.envrc
|
||||||
result
|
result
|
||||||
example.json
|
example.json
|
||||||
./gokill
|
gokill
|
||||||
output.md
|
output.md
|
||||||
thoughts.md
|
thoughts.md
|
||||||
|
deb-single*
|
||||||
|
|||||||
107
README.md
107
README.md
@@ -1,27 +1,52 @@
|
|||||||
# gokill
|
# gokill
|
||||||
'gokill' is a tool that completes some actions when a certain event occurs.
|
|
||||||
actions can vary from shuting down the machine to sending mails over erasing data.
|
|
||||||
actions can be triggert by certain conditions like specific outcomes of unix
|
|
||||||
comands or not having internet connection.
|
|
||||||
|
|
||||||
actions and triggers should be easy to extend and handled like plugins. they
|
gokill is a [software dead man's switch](https://en.wikipedia.org/wiki/Dead_man%27s_switch#Software) that empowers users to configure various events. If these events occur, they trigger predefined actions.
|
||||||
also should be self documenting.
|
The tool is designed for activists, journalists, and individuals who require robust protection for their data, ensuring it remains inaccessible under any circumstances. It belongs to the category of anti-forensic tools, providing a means to safeguard against potential repression. It is specifically crafted for worst-case scenarios, such as when intruders gain physical access to a device. In these intense situations, gokill can automatically perform tasks to enhance your security. Those could be:
|
||||||
every action and trigger should be testable at anytime as a 'dry-run'.
|
- locking the screen
|
||||||
actions can have a 'stage' defined. the lowest stage is started first,
|
- sending chat messages
|
||||||
and only when all actions on that stage are finished next stage is triggered
|
- deleting data
|
||||||
|
- encrypting partitions
|
||||||
|
- destroying encrypted partitions
|
||||||
|
- ect
|
||||||
|
|
||||||
gokill should run as daemon. config should be read from /etc/somename/config.json
|
#### documentation
|
||||||
|
A full list of Triggers and Actions with all their configuration options can be found here:
|
||||||
|
|
||||||
|
## usage
|
||||||
|
If you use NixOS gokill can easily be integrated into your system configuration - scroll down for more info on that.
|
||||||
|
|
||||||
|
For all other linux distributions gokill currently needs to be built and setup manually. This is supposed to change.
|
||||||
|
Iam currently working/researching on publishing gokill as [ppa](https://help.launchpad.net/Packaging/PPA) and as snap.
|
||||||
|
If you have other recommendations let me know.
|
||||||
|
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# Clone the gokill repository
|
||||||
|
git clone https://github.com/k4lipso/gokill
|
||||||
|
cd gokill
|
||||||
|
|
||||||
|
# Build gokill - requires libolm
|
||||||
|
go build github.com/k4lipso/gokill
|
||||||
|
|
||||||
|
# Create a config.json and run gokill
|
||||||
|
./gokill -c config.json
|
||||||
|
# Running gokill manually is annoying, it is acutally meant to run as systemd unit.
|
||||||
|
```
|
||||||
|
|
||||||
## Config Example
|
## Config Example
|
||||||
|
|
||||||
|
gokill is configured using a json file. it consists of a list of triggers, where each of the triggers as a list of
|
||||||
|
actions that will be executed once triggered.
|
||||||
|
|
||||||
``` json
|
``` json
|
||||||
[ //list of triggers
|
[ //list of triggers
|
||||||
{
|
{
|
||||||
"type": "UsbDisconnect",
|
"type": "UsbDisconnect", //triggers when the given device is disconnected
|
||||||
"name": "First Trigger",
|
"name": "First Trigger",
|
||||||
"options": {
|
"options": {
|
||||||
"deviceId": "ata-Samsung_SSD_860_EVO_1TB_S4AALKWJDI102",
|
"deviceId": "ata-Samsung_SSD_860_EVO_1TB_S4AALKWJDI102",
|
||||||
"waitTillConnected": true //only trigger when usb drive was actually attached before
|
"waitTillConnected": true //only trigger when usb drive was actually attached before
|
||||||
}
|
},
|
||||||
"actions": [ //list of actions that will be executed when triggered
|
"actions": [ //list of actions that will be executed when triggered
|
||||||
{
|
{
|
||||||
"name": "unixCommand",
|
"name": "unixCommand",
|
||||||
@@ -31,17 +56,15 @@ gokill should run as daemon. config should be read from /etc/somename/config.jso
|
|||||||
"stage": 2 // defines the order in which actions are triggered.
|
"stage": 2 // defines the order in which actions are triggered.
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "sendMail",
|
"type": "SendTelegram",
|
||||||
"options": {
|
"options": {
|
||||||
"smtpserver": "domain.org",
|
"token": "3345823487:FFGdEFxc1pA18d02Akslw-lkwjdA92KAH2",
|
||||||
"port": 667,
|
"chatId": -832325872,
|
||||||
"recipients": [ "mail1@host.org", "mail2@host.org" ],
|
"message": "attention, intruders got my device!",
|
||||||
"message": "kill switch was triggered",
|
"testMessage": "this is just a test, no worries"
|
||||||
"attachments": [ "/path/atachments" ],
|
},
|
||||||
"pubkeys": "/path/to/keys.pub"
|
|
||||||
},
|
|
||||||
"stage": 1 //this event is triggered first, then the shutdown
|
"stage": 1 //this event is triggered first, then the shutdown
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -49,12 +72,12 @@ gokill should run as daemon. config should be read from /etc/somename/config.jso
|
|||||||
"name": "Second Trigger",
|
"name": "Second Trigger",
|
||||||
"options": {
|
"options": {
|
||||||
"interfaceName": "eth0",
|
"interfaceName": "eth0",
|
||||||
}
|
},
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"name": "unixCommand",
|
"name": "unixCommand",
|
||||||
"options": {
|
"options": {
|
||||||
"command": "env DISPLAY=:0 sudo su -c i3lock someUser"
|
"command": "env DISPLAY=:0 sudo su -c i3lock someUser" //example of locking someUser's screen as root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -63,9 +86,10 @@ gokill should run as daemon. config should be read from /etc/somename/config.jso
|
|||||||
```
|
```
|
||||||
|
|
||||||
## nix support
|
## nix support
|
||||||
|
|
||||||
gokill enjoys full nix support. gokill exposes a nix flakes that outputs a gokill package, a nixosModule and more.
|
gokill enjoys full nix support. gokill exposes a nix flakes that outputs a gokill package, a nixosModule and more.
|
||||||
That means you can super easily incorporate gokill into your existing nixosConfigurations.
|
That means you can super easily incorporate gokill into your existing nixosConfigurations.
|
||||||
|
|
||||||
|
### NixOS Module
|
||||||
Here is a small example config:
|
Here is a small example config:
|
||||||
|
|
||||||
``` nix
|
``` nix
|
||||||
@@ -94,25 +118,48 @@ Here is a small example config:
|
|||||||
|
|
||||||
This will automatically configure and enable a systemd running gokill as root user in the background
|
This will automatically configure and enable a systemd running gokill as root user in the background
|
||||||
|
|
||||||
## actions
|
### Build Documentation locally
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
nix run github:k4lipso/gokill#docs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run integrations tests
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
nix flake check github:k4lipso/gokill
|
||||||
|
```
|
||||||
|
|
||||||
|
## todos
|
||||||
|
|
||||||
|
- export snap
|
||||||
|
- export ppa
|
||||||
|
|
||||||
|
### actions
|
||||||
- [x] shutdown
|
- [x] shutdown
|
||||||
- [ ] wipe ram
|
- [ ] wipe ram
|
||||||
- [ ] send mail
|
- [ ] ~~send mail~~
|
||||||
|
- send chat message
|
||||||
|
- [x] telegram
|
||||||
|
- [x] matrix
|
||||||
- [ ] delete data
|
- [ ] delete data
|
||||||
- [ ] shred area
|
- [ ] shred area
|
||||||
- [x] random command
|
- [x] run command
|
||||||
- [ ] wordpress post
|
- [ ] wordpress post
|
||||||
- [ ] ipfs command
|
- [ ] ipfs command
|
||||||
- [ ] [buskill 'triggers'](https://github.com/BusKill/awesome-buskill-triggers)
|
- [buskill 'triggers'](https://github.com/BusKill/awesome-buskill-triggers)
|
||||||
- [x] [lock-screen](https://github.com/BusKill/buskill-linux/tree/master/triggers)
|
- [x] [lock-screen](https://github.com/BusKill/buskill-linux/tree/master/triggers)
|
||||||
- [x] shutdown
|
- [x] shutdown
|
||||||
- [ ] luks header shredder
|
- [ ] luks header shredder
|
||||||
- [ ] veracrypt self-destruct
|
- [ ] veracrypt self-destruct
|
||||||
|
|
||||||
## Triggers
|
### triggers
|
||||||
- [ ] no internet
|
- [ ] no internet
|
||||||
- [x] [pull usb stick](https://github.com/deepakjois/gousbdrivedetector/blob/master/usbdrivedetector_linux.go)
|
- [x] [pull usb stick](https://github.com/deepakjois/gousbdrivedetector/blob/master/usbdrivedetector_linux.go)
|
||||||
- [x] ethernet unplugged
|
- [x] ethernet unplugged
|
||||||
|
- receive specific chat message
|
||||||
|
- [x] telegram
|
||||||
|
- [ ] matrix
|
||||||
- [ ] power adapter disconnected
|
- [ ] power adapter disconnected
|
||||||
- [ ] unix command
|
- [ ] unix command
|
||||||
- anyOf
|
- anyOf
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ActionResultChan chan error
|
type ActionResultChan chan error
|
||||||
@@ -36,7 +36,7 @@ func (a StagedActions) executeInternal(f func(Action)) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Execute Stage %v\n", idx+1)
|
internal.Log.Infof("Execute Stage %v", idx+1)
|
||||||
for actionidx, _ := range stage.Actions {
|
for actionidx, _ := range stage.Actions {
|
||||||
go f(stage.Actions[actionidx])
|
go f(stage.Actions[actionidx])
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ func (a StagedActions) executeInternal(f func(Action)) {
|
|||||||
err := <-a.ActionChan
|
err := <-a.ActionChan
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error occured on Stage %d: %s\n", idx+1, err)
|
internal.Log.Errorf("Error occured on Stage %d: %s", idx+1, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,9 +121,11 @@ func GetAllActions() []DocumentedAction {
|
|||||||
return []DocumentedAction{
|
return []DocumentedAction{
|
||||||
Command{},
|
Command{},
|
||||||
Printer{},
|
Printer{},
|
||||||
|
RemoveFiles{},
|
||||||
ShellScript{},
|
ShellScript{},
|
||||||
Shutdown{},
|
Shutdown{},
|
||||||
SendMatrix{},
|
SendMatrix{},
|
||||||
|
SendTelegram{},
|
||||||
TimeOut{},
|
TimeOut{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ package actions
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Printer struct {
|
type Printer struct {
|
||||||
@@ -13,12 +12,12 @@ type Printer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) Execute() {
|
func (p Printer) Execute() {
|
||||||
fmt.Printf("Print action fires. Message: %s\n", p.Message)
|
internal.LogDoc(p).Infof("Print action fires. Message: %s", p.Message)
|
||||||
p.ActionChan <- nil
|
p.ActionChan <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) DryExecute() {
|
func (p Printer) DryExecute() {
|
||||||
fmt.Printf("Print action fire test. Message: %s\n", p.Message)
|
internal.LogDoc(p).Infof("Print action fire test. Message: %s", p.Message)
|
||||||
p.ActionChan <- nil
|
p.ActionChan <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
130
actions/remove_files.go
Normal file
130
actions/remove_files.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package actions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/k4lipso/gokill/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoveFiles struct {
|
||||||
|
Files []string `json:"files"`
|
||||||
|
Directories []string `json:"directories"`
|
||||||
|
ActionChan ActionResultChan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c RemoveFiles) getRemoveCommand() string {
|
||||||
|
command := "srm"
|
||||||
|
isAvailable := isCommandAvailable(command)
|
||||||
|
|
||||||
|
if !isAvailable {
|
||||||
|
internal.LogDoc(c).Warningf("Command %s not found, falling back to 'rm'", command)
|
||||||
|
command = "rm"
|
||||||
|
}
|
||||||
|
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c RemoveFiles) DryExecute() {
|
||||||
|
internal.LogDoc(c).Infof("Test Execute")
|
||||||
|
|
||||||
|
command := c.getRemoveCommand()
|
||||||
|
internal.LogDoc(c).Info("The following commands would have been executed:")
|
||||||
|
|
||||||
|
for _, file := range c.Files {
|
||||||
|
internal.LogDoc(c).Noticef("%s -f %s", command, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dir := range c.Directories {
|
||||||
|
internal.LogDoc(c).Noticef("%s -rf %s", command, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ActionChan <- nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c RemoveFiles) Execute() {
|
||||||
|
internal.LogDoc(c).Infof("Execute")
|
||||||
|
|
||||||
|
command := c.getRemoveCommand()
|
||||||
|
|
||||||
|
for _, file := range c.Files {
|
||||||
|
cmd := exec.Command(command, "-fv", file)
|
||||||
|
|
||||||
|
stdout, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
internal.LogDoc(c).Errorf("%s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal.LogDoc(c).Notice(string(stdout))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dir := range c.Directories {
|
||||||
|
cmd := exec.Command(command, "-rfv", dir)
|
||||||
|
|
||||||
|
stdout, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
internal.LogDoc(c).Errorf("%s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal.LogDoc(c).Notice(string(stdout))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ActionChan <- nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateRemoveFiles(config internal.ActionConfig, c ActionResultChan) (RemoveFiles, error) {
|
||||||
|
result := RemoveFiles{}
|
||||||
|
|
||||||
|
err := json.Unmarshal(config.Options, &result)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return RemoveFiles{}, fmt.Errorf("Error parsing RemoveFiles: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.ActionChan = c
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc RemoveFiles) Create(config internal.ActionConfig, c ActionResultChan) (Action, error) {
|
||||||
|
return CreateRemoveFiles(config, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p RemoveFiles) GetName() string {
|
||||||
|
return "RemoveFiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p RemoveFiles) GetDescription() string {
|
||||||
|
return `
|
||||||
|
RemoveFiles deletes the given files and directories.
|
||||||
|
If available "srm" is used, otherwise RemoveFiles falls back to "rm"
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p RemoveFiles) GetExample() string {
|
||||||
|
return `
|
||||||
|
{
|
||||||
|
"type": "RemoveFiles",
|
||||||
|
"options": {
|
||||||
|
"files": [
|
||||||
|
"/home/user/secrets.txt"
|
||||||
|
],
|
||||||
|
"directories": [
|
||||||
|
"/home/user/.gpg",
|
||||||
|
"/home/user/.ssh",
|
||||||
|
"/home/user/.thunderbird"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p RemoveFiles) GetOptions() []internal.ConfigOption {
|
||||||
|
return []internal.ConfigOption{
|
||||||
|
{"files", "[]string", "list of absolute paths of files that should be deleted.", ""},
|
||||||
|
{"directories", "[]string", "list of absolute paths of directories that should be deleted.", ""},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
"maunium.net/go/mautrix/id"
|
"maunium.net/go/mautrix/id"
|
||||||
"maunium.net/go/mautrix/crypto/cryptohelper"
|
"maunium.net/go/mautrix/crypto/cryptohelper"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SendMatrix struct {
|
type SendMatrix struct {
|
||||||
@@ -53,7 +53,7 @@ func (s SendMatrix) sendMessage(message string) error {
|
|||||||
|
|
||||||
client.Crypto = cryptoHelper
|
client.Crypto = cryptoHelper
|
||||||
|
|
||||||
fmt.Println("Matrix Client Now running")
|
internal.LogDoc(s).Info("Matrix Client Now running")
|
||||||
syncCtx, cancelSync := context.WithCancel(context.Background())
|
syncCtx, cancelSync := context.WithCancel(context.Background())
|
||||||
var syncStopWait sync.WaitGroup
|
var syncStopWait sync.WaitGroup
|
||||||
syncStopWait.Add(1)
|
syncStopWait.Add(1)
|
||||||
@@ -72,8 +72,8 @@ func (s SendMatrix) sendMessage(message string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to send event")
|
return fmt.Errorf("Failed to send event")
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Matrix Client: Message sent")
|
internal.LogDoc(s).Info("Matrix Client: Message sent")
|
||||||
fmt.Printf("Matrix Client: event_id: %s", resp.EventID.String())
|
internal.LogDoc(s).Infof("Matrix Client: event_id: %s", resp.EventID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelSync()
|
cancelSync()
|
||||||
@@ -87,22 +87,22 @@ func (s SendMatrix) sendMessage(message string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s SendMatrix) DryExecute() {
|
func (s SendMatrix) DryExecute() {
|
||||||
fmt.Println("SendMatrix: Trying to send test message")
|
internal.LogDoc(s).Info("SendMatrix: Trying to send test message")
|
||||||
err := s.sendMessage(s.TestMessage)
|
err := s.sendMessage(s.TestMessage)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("SendMatrix: failed to send test message")
|
internal.LogDoc(s).Info("SendMatrix: failed to send test message")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ActionChan <- err
|
s.ActionChan <- err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SendMatrix) Execute() {
|
func (s SendMatrix) Execute() {
|
||||||
fmt.Println("SendMatrix: Trying to send test message")
|
internal.LogDoc(s).Info("SendMatrix: Trying to send message")
|
||||||
err := s.sendMessage(s.Message)
|
err := s.sendMessage(s.Message)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("SendMatrix: failed to send test message")
|
internal.LogDoc(s).Info("SendMatrix: failed to send message")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ActionChan <- err
|
s.ActionChan <- err
|
||||||
|
|||||||
148
actions/send_telegram.go
Normal file
148
actions/send_telegram.go
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
package actions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"encoding/json"
|
||||||
|
//"strconv"
|
||||||
|
|
||||||
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
|
||||||
|
"github.com/k4lipso/gokill/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendTelegram struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
ChatId int64 `json:"chatId"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
TestMessage string `json:"testMessage"`
|
||||||
|
ActionChan ActionResultChan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SendTelegram) sendMessage(message string) error {
|
||||||
|
bot, err := tgbotapi.NewBotAPI(s.Token)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("SendTelegram sendMessage error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.Debug = false
|
||||||
|
u := tgbotapi.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
|
||||||
|
chatId := s.ChatId
|
||||||
|
msg := tgbotapi.NewMessage(chatId, message)
|
||||||
|
_, err = bot.Send(msg)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("SendTelegram sendMessage error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SendTelegram) DryExecute() {
|
||||||
|
internal.LogDoc(s).Info("SendTelegram: Trying to send test message")
|
||||||
|
err := s.sendMessage(s.TestMessage)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
internal.LogDoc(s).Info("SendTelegram: failed to send test message")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ActionChan <- err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SendTelegram) Execute() {
|
||||||
|
internal.LogDoc(s).Info("SendTelegram: Trying to send message")
|
||||||
|
err := s.sendMessage(s.Message)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
internal.LogDoc(s).Info("SendTelegram: failed to send message")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ActionChan <- err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSendTelegram(config internal.ActionConfig, c ActionResultChan) (SendTelegram, error) {
|
||||||
|
result := SendTelegram{
|
||||||
|
ChatId: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(config.Options, &result)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return SendTelegram{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.Token == "" {
|
||||||
|
return SendTelegram{}, internal.OptionMissingError{"token"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.ChatId == 0 {
|
||||||
|
return SendTelegram{}, internal.OptionMissingError{"chatId"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.Message == "" {
|
||||||
|
return SendTelegram{}, internal.OptionMissingError{"message"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.TestMessage == "" {
|
||||||
|
return SendTelegram{}, internal.OptionMissingError{"testMessage"}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.ActionChan = c
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SendTelegram) Create(config internal.ActionConfig, c ActionResultChan) (Action, error) {
|
||||||
|
return CreateSendTelegram(config, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SendTelegram) GetName() string {
|
||||||
|
return "SendTelegram"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SendTelegram) GetDescription() string {
|
||||||
|
return "Sends a message to a given room. The user needs to be part of that room already."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SendTelegram) GetExample() string {
|
||||||
|
return `
|
||||||
|
{
|
||||||
|
"type": "SendTelegram",
|
||||||
|
"options": {
|
||||||
|
"token": "5349923487:FFGrETxa0pA29d02Akslw-lkwjdA92KAH2",
|
||||||
|
"chatId": -832345892,
|
||||||
|
"message": "attention, intruders got my device!",
|
||||||
|
"testMessage": "this is just a test, no worries"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SendTelegram) GetOptions() []internal.ConfigOption {
|
||||||
|
return []internal.ConfigOption{
|
||||||
|
{
|
||||||
|
Name: "token",
|
||||||
|
Type: "string",
|
||||||
|
Description: "telegram bot token (ask botfather)",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "chatId",
|
||||||
|
Type: "int",
|
||||||
|
Description: "chatId of group or chat you want the message be sent to.",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "message",
|
||||||
|
Type: "string",
|
||||||
|
Description: "actual message that should be sent",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "testMessage",
|
||||||
|
Type: "string",
|
||||||
|
Description: "message sent during test run",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ShellScript struct {
|
type ShellScript struct {
|
||||||
@@ -18,7 +18,6 @@ func isExecutableFile(path string) bool {
|
|||||||
fi, err := os.Lstat(path)
|
fi, err := os.Lstat(path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Test executing Shellscript Failed.")
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,18 +32,18 @@ func isExecutableFile(path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c ShellScript) DryExecute() {
|
func (c ShellScript) DryExecute() {
|
||||||
fmt.Printf("Test Executing ShellScript:\n%s\n", c.Path)
|
internal.LogDoc(c).Infof("Test Executing ShellScript:\n%s", c.Path)
|
||||||
|
|
||||||
_, err := os.Open(c.Path)
|
_, err := os.Open(c.Path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Test executing Shellscript Failed.")
|
internal.LogDoc(c).Warning("Test executing Shellscript Failed.")
|
||||||
c.ActionChan <- err
|
c.ActionChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isExecutableFile(c.Path) {
|
if !isExecutableFile(c.Path) {
|
||||||
fmt.Println("Test executing Shellscript Failed.")
|
internal.LogDoc(c).Warning("Test executing Shellscript Failed.")
|
||||||
c.ActionChan <- fmt.Errorf("File is not executable: %s", c.Path)
|
c.ActionChan <- fmt.Errorf("File is not executable: %s", c.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -54,7 +53,7 @@ func (c ShellScript) DryExecute() {
|
|||||||
|
|
||||||
func (c ShellScript) Execute() {
|
func (c ShellScript) Execute() {
|
||||||
if !isExecutableFile(c.Path) {
|
if !isExecutableFile(c.Path) {
|
||||||
fmt.Println("Test executing Shellscript Failed.")
|
internal.LogDoc(c).Warning("Executing Shellscript Failed.")
|
||||||
c.ActionChan <- fmt.Errorf("File is not executable: %s", c.Path)
|
c.ActionChan <- fmt.Errorf("File is not executable: %s", c.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -64,11 +63,11 @@ func (c ShellScript) Execute() {
|
|||||||
stdout, err := cmd.Output()
|
stdout, err := cmd.Output()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
internal.LogDoc(c).Warning("Failed to execute Shellscript")
|
||||||
c.ActionChan <- err
|
c.ActionChan <- fmt.Errorf("Error during ShellScript execute: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(stdout[:]))
|
internal.LogDoc(c).Infof("Shellscript output:\n%s", string(stdout[:]))
|
||||||
c.ActionChan <- nil
|
c.ActionChan <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package actions
|
package actions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Shutdown struct {
|
type Shutdown struct {
|
||||||
@@ -14,27 +13,30 @@ type Shutdown struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s Shutdown) DryExecute() {
|
func (s Shutdown) DryExecute() {
|
||||||
fmt.Printf("shutdown -h %s\n", s.Timeout)
|
internal.LogDoc(s).Infof("shutdown -h %s", s.Timeout)
|
||||||
fmt.Println("Test Shutdown executed...")
|
internal.LogDoc(s).Info("Test Shutdown executed...")
|
||||||
s.ActionChan <- nil
|
s.ActionChan <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Shutdown) Execute() {
|
func (s Shutdown) Execute() {
|
||||||
if err := exec.Command("shutdown", "-h", s.Timeout).Run(); err != nil {
|
if err := exec.Command("shutdown", "-h", s.Timeout).Run(); err != nil {
|
||||||
fmt.Println("Failed to initiate shutdown:", err)
|
internal.LogDoc(s).Errorf("Failed to initiate shutdown: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Shutdown executed...")
|
internal.LogDoc(s).Notice("Shutdown executed...")
|
||||||
|
|
||||||
s.ActionChan <- nil
|
s.ActionChan <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Shutdown) Create(config internal.ActionConfig, c ActionResultChan) (Action, error) {
|
func (s Shutdown) Create(config internal.ActionConfig, c ActionResultChan) (Action, error) {
|
||||||
var result Shutdown
|
result := Shutdown{
|
||||||
|
Timeout: "now",
|
||||||
|
}
|
||||||
|
|
||||||
err := json.Unmarshal(config.Options, &result)
|
err := json.Unmarshal(config.Options, &result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Parsing Shutdown options failed.")
|
internal.LogDoc(s).Warning("Parsing Shutdown options failed.")
|
||||||
return Shutdown{}, err
|
return Shutdown{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ package actions
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TimeOut struct {
|
type TimeOut struct {
|
||||||
@@ -18,7 +17,7 @@ func (t TimeOut) DryExecute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t TimeOut) Execute() {
|
func (t TimeOut) Execute() {
|
||||||
fmt.Printf("Waiting %d seconds\n", t.Duration)
|
internal.LogDoc(t).Infof("Waiting %d seconds", t.Duration)
|
||||||
time.Sleep(time.Duration(t.Duration) * time.Second)
|
time.Sleep(time.Duration(t.Duration) * time.Second)
|
||||||
t.ActionChan <- nil
|
t.ActionChan <- nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
@@ -24,19 +24,19 @@ func isCommandAvailable(name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Command) DryExecute() {
|
func (c Command) DryExecute() {
|
||||||
fmt.Printf("Test Executing Command:\n%s\n", c.Command)
|
internal.LogDoc(c).Infof("Test Executing Command: %s", c.Command)
|
||||||
command, _, err := c.splitCommandString()
|
command, _, err := c.splitCommandString()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error during argument parsing of command '%s'\n", c.Command)
|
internal.LogDoc(c).Errorf("Error during argument parsing of command '%s'", c.Command)
|
||||||
fmt.Println(err)
|
c.ActionChan <- fmt.Errorf("Error on Command action: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isAvailable := isCommandAvailable(command)
|
isAvailable := isCommandAvailable(command)
|
||||||
|
|
||||||
if !isAvailable {
|
if !isAvailable {
|
||||||
fmt.Printf("Command %s not found\n", command)
|
internal.LogDoc(c).Warningf("Command %s not found", command)
|
||||||
c.ActionChan <- fmt.Errorf("Command %s not found!", command)
|
c.ActionChan <- fmt.Errorf("Command %s not found!", command)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ func (c Command) splitCommandString() (string, []string, error) {
|
|||||||
|
|
||||||
func (c Command) Execute() {
|
func (c Command) Execute() {
|
||||||
command, args, err := c.splitCommandString()
|
command, args, err := c.splitCommandString()
|
||||||
fmt.Println("Executing command: ", c.Command)
|
internal.LogDoc(c).Infof("Executing command: ", c.Command)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ActionChan <- err
|
c.ActionChan <- err
|
||||||
@@ -72,11 +72,11 @@ func (c Command) Execute() {
|
|||||||
stdout, err := cmd.Output()
|
stdout, err := cmd.Output()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
internal.LogDoc(c).Errorf("%s", err.Error())
|
||||||
c.ActionChan <- err
|
c.ActionChan <- fmt.Errorf("Executing Command '%s' failed: %s", c.Command, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(stdout[:]))
|
internal.LogDoc(c).Infof("Command Output:\n%s", string(stdout[:]))
|
||||||
|
|
||||||
c.ActionChan <- nil
|
c.ActionChan <- nil
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ func (p Command) GetName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p Command) GetDescription() string {
|
func (p Command) GetDescription() string {
|
||||||
return "Invoces given command using exec."
|
return "Invokes given command using exec."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Command) GetExample() string {
|
func (p Command) GetExample() string {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"flag"
|
"flag"
|
||||||
|
|
||||||
"unknown.com/gokill/actions"
|
"github.com/k4lipso/gokill/actions"
|
||||||
"unknown.com/gokill/triggers"
|
"github.com/k4lipso/gokill/triggers"
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getMarkdown(documenter internal.Documenter) string {
|
func getMarkdown(documenter internal.Documenter) string {
|
||||||
@@ -37,7 +37,7 @@ func writeToFile(path string, documenter internal.Documenter) error {
|
|||||||
f, err := os.Create(fileName)
|
f, err := os.Create(fileName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
internal.Log.Errorf("Error during writeToFile: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func writeToFile(path string, documenter internal.Documenter) error {
|
|||||||
_, err = f.WriteString(getMarkdown(documenter))
|
_, err = f.WriteString(getMarkdown(documenter))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
internal.Log.Errorf("Error during writeToFile: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,9 +86,12 @@ func printDocumentersSummary() {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
outputPath := flag.String("output", "", "path where docs/ shoud be created")
|
outputPath := flag.String("output", "", "path where docs/ shoud be created")
|
||||||
|
verbose := flag.Bool("verbose", false, "log debug information")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
internal.InitLogger()
|
||||||
|
internal.SetVerbose(*verbose)
|
||||||
|
|
||||||
if *outputPath == "" {
|
if *outputPath == "" {
|
||||||
printDocumentersSummary()
|
printDocumentersSummary()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"unknown.com/gokill/actions"
|
"github.com/k4lipso/gokill/actions"
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
"unknown.com/gokill/triggers"
|
"github.com/k4lipso/gokill/triggers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetDocumentation() string {
|
func GetDocumentation() string {
|
||||||
@@ -37,19 +37,24 @@ func GetDocumentation() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
configFilePath := flag.String("c", "", "path to config file")
|
configFilePath := flag.String("c", "", "path to config file")
|
||||||
showDoc := flag.Bool("d", false, "show doc")
|
showDoc := flag.Bool("d", false, "show doc")
|
||||||
testRun := flag.Bool("t", false, "test run")
|
testRun := flag.Bool("t", false, "test run")
|
||||||
|
verbose := flag.Bool("verbose", false, "log debug info")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
internal.InitLogger()
|
||||||
|
internal.SetVerbose(*verbose)
|
||||||
|
|
||||||
if *showDoc {
|
if *showDoc {
|
||||||
fmt.Print(GetDocumentation())
|
fmt.Print(GetDocumentation())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *configFilePath == "" {
|
if *configFilePath == "" {
|
||||||
fmt.Println("No config file given. Use --help to show usage.")
|
internal.Log.Warning("No config file given. Use --help to show usage.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +63,7 @@ func main() {
|
|||||||
configFile, err := os.ReadFile(*configFilePath)
|
configFile, err := os.ReadFile(*configFilePath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error loading config file: ", err)
|
internal.Log.Errorf("Error loading config file: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +71,7 @@ func main() {
|
|||||||
err = json.Unmarshal(configFile, &f)
|
err = json.Unmarshal(configFile, &f)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
internal.Log.Errorf("Error pasing json file: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +80,7 @@ func main() {
|
|||||||
trigger, err := triggers.NewTrigger(cfg)
|
trigger, err := triggers.NewTrigger(cfg)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
internal.Log.Errorf("%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
flake.lock
generated
42
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1698553279,
|
"lastModified": 1699343069,
|
||||||
"narHash": "sha256-T/9P8yBSLcqo/v+FTOBK+0rjzjPMctVymZydbvR/Fak=",
|
"narHash": "sha256-s7BBhyLA6MI6FuJgs4F/SgpntHBzz40/qV0xLPW6A1Q=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "90e85bc7c1a6fc0760a94ace129d3a1c61c3d035",
|
"rev": "ec750fd01963ab6b20ee1f0cb488754e8036d89d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -18,7 +18,41 @@
|
|||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs",
|
||||||
|
"utils": "utils"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1694529238,
|
||||||
|
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
115
flake.nix
115
flake.nix
@@ -4,13 +4,18 @@
|
|||||||
#nixpkgs for testing framework
|
#nixpkgs for testing framework
|
||||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
|
||||||
outputs = { self, nixpkgs, ... }:
|
inputs.utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, utils, ... }:
|
||||||
|
|
||||||
|
nixpkgs.lib.attrsets.recursiveUpdate
|
||||||
|
(utils.lib.eachSystem (utils.lib.defaultSystems) ( system:
|
||||||
let
|
let
|
||||||
forAllSystems = nixpkgs.lib.genAttrs [ "x86_64-linux" ];
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
pkgs = nixpkgs.legacyPackages."x86_64-linux";
|
currentVendorHash = "sha256-Q14p7L2Ez/kvBhMUxlyMA1I/XEIxgSXOp4dpmH/SQyI=";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
devShell."x86_64-linux" = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
go
|
go
|
||||||
gotools
|
gotools
|
||||||
@@ -19,40 +24,52 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.x86_64-linux.gokill = nixpkgs.legacyPackages.x86_64-linux.buildGoModule rec {
|
packages = {
|
||||||
pname = "gokill";
|
gokill = pkgs.buildGoModule rec {
|
||||||
version = "1.0";
|
pname = "gokill";
|
||||||
vendorHash = "sha256-MVIvXxASUO33Ca34ruIz4S0QDJcW2unaG4+Zo73g/9o=";
|
version = "1.0";
|
||||||
src = ./.;
|
vendorHash = currentVendorHash;
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
pkgs.olm
|
pkgs.olm
|
||||||
];
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
gokill-docbuilder = pkgs.buildGoModule rec {
|
||||||
|
pname = "docbuilder";
|
||||||
|
version = "1.0";
|
||||||
|
vendorHash = currentVendorHash;
|
||||||
|
buildFLags = "-o . $dest/cmd/gokill/docbuilder";
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.olm
|
||||||
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
docs = pkgs.callPackage (import ./docs/default.nix) { self = self; };
|
||||||
|
|
||||||
|
default = self.packages.${system}.gokill;
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.x86_64-linux.gokill-docbuilder = nixpkgs.legacyPackages.x86_64-linux.buildGoModule rec {
|
apps = {
|
||||||
pname = "docbuilder";
|
docs = {
|
||||||
version = "1.0";
|
type = "app";
|
||||||
vendorHash = "sha256-MVIvXxASUO33Ca34ruIz4S0QDJcW2unaG4+Zo73g/9o=";
|
program = builtins.toString (pkgs.writeScript "docs" ''
|
||||||
buildFLags = "-o . $dest/cmd/gokill/docbuilder";
|
${pkgs.python3}/bin/python3 -m http.server --directory ${self.packages."${system}".docs}/share/doc'');
|
||||||
src = ./.;
|
};
|
||||||
|
|
||||||
buildInputs = [
|
|
||||||
pkgs.olm
|
|
||||||
];
|
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
})) ({
|
||||||
packages.x86_64-linux.docs = pkgs.callPackage (import ./docs/default.nix) { self = self; };
|
|
||||||
|
|
||||||
packages.x86_64-linux.default = self.packages.x86_64-linux.gokill;
|
|
||||||
|
|
||||||
nixosModules.gokill = import ./nixos-modules/gokill.nix { self = self; };
|
nixosModules.gokill = import ./nixos-modules/gokill.nix { self = self; };
|
||||||
|
|
||||||
packages.x86_64-linux.testVm =
|
packages.x86_64-linux.testVm =
|
||||||
@@ -64,6 +81,7 @@
|
|||||||
self.nixosModules.gokill
|
self.nixosModules.gokill
|
||||||
{
|
{
|
||||||
services.gokill.enable = true;
|
services.gokill.enable = true;
|
||||||
|
services.gokill.testRun = false;
|
||||||
services.gokill.triggers = [
|
services.gokill.triggers = [
|
||||||
{
|
{
|
||||||
type = "Timeout";
|
type = "Timeout";
|
||||||
@@ -72,19 +90,12 @@
|
|||||||
duration = 10;
|
duration = 10;
|
||||||
};
|
};
|
||||||
actions = [
|
actions = [
|
||||||
{
|
{
|
||||||
type = "Timeout";
|
type = "Shutdown";
|
||||||
options = {
|
options = {
|
||||||
duration = 5;
|
};
|
||||||
};
|
stage = 2;
|
||||||
stage = 1;
|
}
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "Shutdown";
|
|
||||||
options = {
|
|
||||||
};
|
|
||||||
stage = 2;
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -104,19 +115,13 @@
|
|||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
|
|
||||||
apps.x86_64-linux.docs = {
|
checks.x86_64-linux = let
|
||||||
type = "app";
|
|
||||||
program = builtins.toString (nixpkgs.legacyPackages."x86_64-linux".writeScript "docs" ''
|
|
||||||
${pkgs.python3}/bin/python3 -m http.server --directory ${self.packages."x86_64-linux".docs}/share/doc'');
|
|
||||||
};
|
|
||||||
|
|
||||||
checks = forAllSystems (system: let
|
|
||||||
checkArgs = {
|
checkArgs = {
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages."x86_64-linux";
|
||||||
inherit self;
|
inherit self;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
gokill = import ./test/test.nix checkArgs;
|
gokill = import ./test/test.nix checkArgs;
|
||||||
});
|
};
|
||||||
};
|
}) ;
|
||||||
}
|
}
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -1,8 +1,10 @@
|
|||||||
module unknown.com/gokill
|
module github.com/k4lipso/gokill
|
||||||
|
|
||||||
go 1.21.3
|
go 1.21.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/apsdehal/go-logger v0.0.0-20190515212710-b0d6ccfee0e6
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||||
github.com/mattn/go-sqlite3 v1.14.17
|
github.com/mattn/go-sqlite3 v1.14.17
|
||||||
maunium.net/go/mautrix v0.16.1
|
maunium.net/go/mautrix v0.16.1
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1,8 +1,12 @@
|
|||||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
|
github.com/apsdehal/go-logger v0.0.0-20190515212710-b0d6ccfee0e6 h1:qISSdUEX4sjDHfdD/vf65fhuCh3pIhiILDB7ktjJrqU=
|
||||||
|
github.com/apsdehal/go-logger v0.0.0-20190515212710-b0d6ccfee0e6/go.mod h1:U3/8D6R9+bVpX0ORZjV+3mU9pQ86m7h1lESgJbXNvXA=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
|||||||
63
internal/logging.go
Normal file
63
internal/logging.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/apsdehal/go-logger"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Log *logger.Logger
|
||||||
|
var documenterLoggers map[string]*logger.Logger
|
||||||
|
var verbose bool
|
||||||
|
|
||||||
|
var formatNormal string = "%{message}"
|
||||||
|
var formatVerbose string = "%{time} %{level}: %{message}"
|
||||||
|
var formatModuleNormal string = "%{module}: %{message}"
|
||||||
|
var formatModuleVerbose string = "%{time} %{level} %{module}: %{message}"
|
||||||
|
|
||||||
|
func InitLogger() error {
|
||||||
|
var err error
|
||||||
|
Log, err = logger.New("UsbDisconnect", 1, os.Stdout)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Logger initialization error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
documenterLoggers = make(map[string]*logger.Logger)
|
||||||
|
verbose = false
|
||||||
|
Log.SetLogLevel(logger.InfoLevel)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func LogDoc(documenter Documenter) *logger.Logger {
|
||||||
|
documenterLogger, ok := documenterLoggers[documenter.GetName()]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
documenterLogger, _ = logger.New(documenter.GetName(), 1, os.Stdout)
|
||||||
|
documenterLoggers[documenter.GetName()] = documenterLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
SetVerbose(verbose)
|
||||||
|
//documenterLogger.SetFormat("%{message}")
|
||||||
|
|
||||||
|
return documenterLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetVerbose(value bool) {
|
||||||
|
verbose = value
|
||||||
|
toggleVerbosity := func(l *logger.Logger, formatN string, formatV string) {
|
||||||
|
if value {
|
||||||
|
l.SetLogLevel(logger.DebugLevel)
|
||||||
|
l.SetFormat(formatV)
|
||||||
|
} else {
|
||||||
|
l.SetLogLevel(logger.InfoLevel)
|
||||||
|
l.SetFormat(formatN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleVerbosity(Log, formatNormal, formatVerbose)
|
||||||
|
for _, documenterLogger := range documenterLoggers {
|
||||||
|
toggleVerbosity(documenterLogger, formatModuleNormal, formatModuleVerbose)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ let
|
|||||||
cfg = config.services.gokill;
|
cfg = config.services.gokill;
|
||||||
configFile = pkgs.writeText "config.json" (builtins.toJSON cfg.triggers);
|
configFile = pkgs.writeText "config.json" (builtins.toJSON cfg.triggers);
|
||||||
gokill-pkg = self.packages.x86_64-linux.gokill;
|
gokill-pkg = self.packages.x86_64-linux.gokill;
|
||||||
|
testRun = if cfg.testRun then "-t" else "";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = with lib; {
|
options = with lib; {
|
||||||
@@ -15,6 +16,14 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testRun = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = mdDoc ''
|
||||||
|
When set to true gokill is performing a test run
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
triggers = mkOption {
|
triggers = mkOption {
|
||||||
description = "list of triggers";
|
description = "list of triggers";
|
||||||
default = [];
|
default = [];
|
||||||
@@ -61,7 +70,7 @@ in
|
|||||||
description = "gokill daemon";
|
description = "gokill daemon";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
ExecStart = "${gokill-pkg}/bin/gokill -c ${configFile}";
|
ExecStart = "${gokill-pkg}/bin/gokill -c ${configFile} ${testRun}";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"unknown.com/gokill/actions"
|
"github.com/k4lipso/gokill/actions"
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EthernetDisconnect struct {
|
type EthernetDisconnect struct {
|
||||||
@@ -20,7 +20,7 @@ func isEthernetConnected(deviceName string) bool {
|
|||||||
content, err := os.ReadFile(fmt.Sprintf("/sys/class/net/%s/operstate", deviceName))
|
content, err := os.ReadFile(fmt.Sprintf("/sys/class/net/%s/operstate", deviceName))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
internal.LogDoc(EthernetDisconnect{}).Errorf("Cant read devices operstate. Check the deviceName. error: %s", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package triggers
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEthernetDisconnetConfig(t *testing.T) {
|
func TestEthernetDisconnetConfig(t *testing.T) {
|
||||||
|
|||||||
135
triggers/receive_telegram.go
Normal file
135
triggers/receive_telegram.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package triggers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
|
||||||
|
"github.com/k4lipso/gokill/internal"
|
||||||
|
"github.com/k4lipso/gokill/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ReceiveTelegram struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
ChatId int64 `json:"chatId"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
action actions.Action
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ReceiveTelegram) Listen() {
|
||||||
|
bot, err := tgbotapi.NewBotAPI(s.Token)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return //fmt.Errorf("ReceiveTelegram waitForMessage error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.Debug = false
|
||||||
|
u := tgbotapi.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(-746157642, "BOT TEST MESSAGE")
|
||||||
|
bot.Send(msg)
|
||||||
|
|
||||||
|
chatId := s.ChatId
|
||||||
|
updates := bot.GetUpdatesChan(u)
|
||||||
|
for update := range updates {
|
||||||
|
if update.Message != nil { // If we got a message
|
||||||
|
if(update.Message.Chat.ID != chatId) {
|
||||||
|
internal.LogDoc(s).Debugf("ReceiveTelegram received wrong ChatId. Got %d, wanted %d", update.Message.Chat.ID, s.ChatId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update.Message.Text != s.Message) {
|
||||||
|
internal.LogDoc(s).Debug("ReceiveTelegram received wrong Message")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
internal.LogDoc(s).Info("ReceiveTelegram received secret message")
|
||||||
|
actions.Fire(s.action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func CreateReceiveTelegram(config internal.KillSwitchConfig) (ReceiveTelegram, error) {
|
||||||
|
result := ReceiveTelegram{
|
||||||
|
ChatId: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(config.Options, &result)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ReceiveTelegram{}, fmt.Errorf("Error during CreateReceiveTelegram: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.Token == "" {
|
||||||
|
return ReceiveTelegram{}, internal.OptionMissingError{"token"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.ChatId == 0 {
|
||||||
|
return ReceiveTelegram{}, internal.OptionMissingError{"chadId"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.Message == "" {
|
||||||
|
return ReceiveTelegram{}, internal.OptionMissingError{"message"}
|
||||||
|
}
|
||||||
|
|
||||||
|
action, err := actions.NewAction(config.Actions)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ReceiveTelegram{}, fmt.Errorf("Error during CreateReceiveTelegram: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.action = action
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ReceiveTelegram) Create(config internal.KillSwitchConfig) (Trigger, error) {
|
||||||
|
return CreateReceiveTelegram(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ReceiveTelegram) GetName() string {
|
||||||
|
return "ReceiveTelegram"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ReceiveTelegram) GetDescription() string {
|
||||||
|
return "Waits for a specific message in a given chat. Once the message is received, the trigger fires."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ReceiveTelegram) GetExample() string {
|
||||||
|
return `
|
||||||
|
{
|
||||||
|
"type": "ReceiveTelegram",
|
||||||
|
"options": {
|
||||||
|
"token": "5349923487:FFGrETxa0pA29d02Akslw-lkwjdA92KAH2",
|
||||||
|
"chatId": -832345892,
|
||||||
|
"message": "secretmessagethatfiresthetrigger"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ReceiveTelegram) GetOptions() []internal.ConfigOption {
|
||||||
|
return []internal.ConfigOption{
|
||||||
|
{
|
||||||
|
Name: "token",
|
||||||
|
Type: "string",
|
||||||
|
Description: "telegram bot token (ask botfather)",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "chatId",
|
||||||
|
Type: "int",
|
||||||
|
Description: "chatId of group or chat you want the message be received from.",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "message",
|
||||||
|
Type: "string",
|
||||||
|
Description: "actual message that, when received, fires the trigger",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package triggers
|
package triggers
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"unknown.com/gokill/actions"
|
"github.com/k4lipso/gokill/actions"
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TimeOut struct {
|
type TimeOut struct {
|
||||||
@@ -14,10 +13,10 @@ type TimeOut struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t TimeOut) Listen() {
|
func (t TimeOut) Listen() {
|
||||||
fmt.Println("TimeOut listens")
|
internal.LogDoc(t).Info("TimeOut listens")
|
||||||
fmt.Println(t.Duration)
|
internal.LogDoc(t).Infof("%d", t.Duration)
|
||||||
time.Sleep(time.Duration(t.Duration) * time.Second)
|
time.Sleep(time.Duration(t.Duration) * time.Second)
|
||||||
fmt.Println("TimeOut fires")
|
internal.LogDoc(t).Notice("TimeOut fires")
|
||||||
actions.Fire(t.action)
|
actions.Fire(t.action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package triggers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Trigger interface {
|
type Trigger interface {
|
||||||
@@ -29,6 +29,7 @@ func NewTrigger(config internal.KillSwitchConfig) (Trigger, error) {
|
|||||||
func GetAllTriggers() []DocumentedTrigger {
|
func GetAllTriggers() []DocumentedTrigger {
|
||||||
return []DocumentedTrigger{
|
return []DocumentedTrigger{
|
||||||
EthernetDisconnect{},
|
EthernetDisconnect{},
|
||||||
|
ReceiveTelegram{},
|
||||||
TimeOut{},
|
TimeOut{},
|
||||||
UsbDisconnect{},
|
UsbDisconnect{},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ package triggers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"unknown.com/gokill/actions"
|
"github.com/k4lipso/gokill/actions"
|
||||||
"unknown.com/gokill/internal"
|
"github.com/k4lipso/gokill/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UsbDisconnect struct {
|
type UsbDisconnect struct {
|
||||||
@@ -35,8 +34,8 @@ func (t UsbDisconnect) Listen() {
|
|||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Device %s detected.\n", t.DeviceName)
|
internal.LogDoc(t).Infof("Device %s detected.", t.DeviceName)
|
||||||
fmt.Println("UsbDisconnect Trigger is Armed")
|
internal.LogDoc(t).Notice("Trigger is Armed")
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|||||||
Reference in New Issue
Block a user