mirror of
https://github.com/postmannen/ctrl.git
synced 2025-03-05 06:46:48 +00:00
added REQHttpGetScheduled
This commit is contained in:
parent
fbeb3bf9f6
commit
b11b8d6baf
4 changed files with 213 additions and 30 deletions
|
@ -5,6 +5,8 @@ type argsString string
|
||||||
|
|
||||||
type centralAuth struct {
|
type centralAuth struct {
|
||||||
schema map[Node]map[argsString]signatureBase32
|
schema map[Node]map[argsString]signatureBase32
|
||||||
|
|
||||||
|
configuration *Configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCentralAuth() *centralAuth {
|
func newCentralAuth() *centralAuth {
|
||||||
|
|
|
@ -105,6 +105,8 @@ type Configuration struct {
|
||||||
StartSubREQToConsole bool
|
StartSubREQToConsole bool
|
||||||
// Subscriber for REQHttpGet
|
// Subscriber for REQHttpGet
|
||||||
StartSubREQHttpGet bool
|
StartSubREQHttpGet bool
|
||||||
|
// Subscriber for REQHttpGetScheduled
|
||||||
|
StartSubREQHttpGetScheduled bool
|
||||||
// Subscriber for tailing log files
|
// Subscriber for tailing log files
|
||||||
StartSubREQTailFile bool
|
StartSubREQTailFile bool
|
||||||
// Subscriber for continously delivery of output from cli commands.
|
// Subscriber for continously delivery of output from cli commands.
|
||||||
|
@ -150,21 +152,22 @@ type ConfigurationFromFile struct {
|
||||||
EnableSignatureCheck *bool
|
EnableSignatureCheck *bool
|
||||||
IsCentralAuth *bool
|
IsCentralAuth *bool
|
||||||
|
|
||||||
StartPubREQHello *int
|
StartPubREQHello *int
|
||||||
StartSubREQErrorLog *bool
|
StartSubREQErrorLog *bool
|
||||||
StartSubREQHello *bool
|
StartSubREQHello *bool
|
||||||
StartSubREQToFileAppend *bool
|
StartSubREQToFileAppend *bool
|
||||||
StartSubREQToFile *bool
|
StartSubREQToFile *bool
|
||||||
StartSubREQCopyFileFrom *bool
|
StartSubREQCopyFileFrom *bool
|
||||||
StartSubREQCopyFileTo *bool
|
StartSubREQCopyFileTo *bool
|
||||||
StartSubREQPing *bool
|
StartSubREQPing *bool
|
||||||
StartSubREQPong *bool
|
StartSubREQPong *bool
|
||||||
StartSubREQCliCommand *bool
|
StartSubREQCliCommand *bool
|
||||||
StartSubREQToConsole *bool
|
StartSubREQToConsole *bool
|
||||||
StartSubREQHttpGet *bool
|
StartSubREQHttpGet *bool
|
||||||
StartSubREQTailFile *bool
|
StartSubREQHttpGetScheduled *bool
|
||||||
StartSubREQCliCommandCont *bool
|
StartSubREQTailFile *bool
|
||||||
StartSubREQRelay *bool
|
StartSubREQCliCommandCont *bool
|
||||||
|
StartSubREQRelay *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfiguration will return a *Configuration.
|
// NewConfiguration will return a *Configuration.
|
||||||
|
@ -208,20 +211,21 @@ func newConfigurationDefaults() Configuration {
|
||||||
EnableSignatureCheck: false,
|
EnableSignatureCheck: false,
|
||||||
IsCentralAuth: false,
|
IsCentralAuth: false,
|
||||||
|
|
||||||
StartSubREQErrorLog: true,
|
StartSubREQErrorLog: true,
|
||||||
StartSubREQHello: true,
|
StartSubREQHello: true,
|
||||||
StartSubREQToFileAppend: true,
|
StartSubREQToFileAppend: true,
|
||||||
StartSubREQToFile: true,
|
StartSubREQToFile: true,
|
||||||
StartSubREQCopyFileFrom: true,
|
StartSubREQCopyFileFrom: true,
|
||||||
StartSubREQCopyFileTo: true,
|
StartSubREQCopyFileTo: true,
|
||||||
StartSubREQPing: true,
|
StartSubREQPing: true,
|
||||||
StartSubREQPong: true,
|
StartSubREQPong: true,
|
||||||
StartSubREQCliCommand: true,
|
StartSubREQCliCommand: true,
|
||||||
StartSubREQToConsole: true,
|
StartSubREQToConsole: true,
|
||||||
StartSubREQHttpGet: true,
|
StartSubREQHttpGet: true,
|
||||||
StartSubREQTailFile: true,
|
StartSubREQHttpGetScheduled: true,
|
||||||
StartSubREQCliCommandCont: true,
|
StartSubREQTailFile: true,
|
||||||
StartSubREQRelay: false,
|
StartSubREQCliCommandCont: true,
|
||||||
|
StartSubREQRelay: false,
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -450,6 +454,11 @@ func checkConfigValues(cf ConfigurationFromFile) Configuration {
|
||||||
} else {
|
} else {
|
||||||
conf.StartSubREQHttpGet = *cf.StartSubREQHttpGet
|
conf.StartSubREQHttpGet = *cf.StartSubREQHttpGet
|
||||||
}
|
}
|
||||||
|
if cf.StartSubREQHttpGetScheduled == nil {
|
||||||
|
conf.StartSubREQHttpGetScheduled = cd.StartSubREQHttpGetScheduled
|
||||||
|
} else {
|
||||||
|
conf.StartSubREQHttpGetScheduled = *cf.StartSubREQHttpGetScheduled
|
||||||
|
}
|
||||||
if cf.StartSubREQTailFile == nil {
|
if cf.StartSubREQTailFile == nil {
|
||||||
conf.StartSubREQTailFile = cd.StartSubREQTailFile
|
conf.StartSubREQTailFile = cd.StartSubREQTailFile
|
||||||
} else {
|
} else {
|
||||||
|
@ -542,6 +551,7 @@ func (c *Configuration) CheckFlags() error {
|
||||||
flag.BoolVar(&c.StartSubREQCliCommand, "startSubREQCliCommand", fc.StartSubREQCliCommand, "true/false")
|
flag.BoolVar(&c.StartSubREQCliCommand, "startSubREQCliCommand", fc.StartSubREQCliCommand, "true/false")
|
||||||
flag.BoolVar(&c.StartSubREQToConsole, "startSubREQToConsole", fc.StartSubREQToConsole, "true/false")
|
flag.BoolVar(&c.StartSubREQToConsole, "startSubREQToConsole", fc.StartSubREQToConsole, "true/false")
|
||||||
flag.BoolVar(&c.StartSubREQHttpGet, "startSubREQHttpGet", fc.StartSubREQHttpGet, "true/false")
|
flag.BoolVar(&c.StartSubREQHttpGet, "startSubREQHttpGet", fc.StartSubREQHttpGet, "true/false")
|
||||||
|
flag.BoolVar(&c.StartSubREQHttpGetScheduled, "startSubREQHttpGetScheduled", fc.StartSubREQHttpGetScheduled, "true/false")
|
||||||
flag.BoolVar(&c.StartSubREQTailFile, "startSubREQTailFile", fc.StartSubREQTailFile, "true/false")
|
flag.BoolVar(&c.StartSubREQTailFile, "startSubREQTailFile", fc.StartSubREQTailFile, "true/false")
|
||||||
flag.BoolVar(&c.StartSubREQCliCommandCont, "startSubREQCliCommandCont", fc.StartSubREQCliCommandCont, "true/false")
|
flag.BoolVar(&c.StartSubREQCliCommandCont, "startSubREQCliCommandCont", fc.StartSubREQCliCommandCont, "true/false")
|
||||||
flag.BoolVar(&c.StartSubREQRelay, "startSubREQRelay", fc.StartSubREQRelay, "true/false")
|
flag.BoolVar(&c.StartSubREQRelay, "startSubREQRelay", fc.StartSubREQRelay, "true/false")
|
||||||
|
|
14
processes.go
14
processes.go
|
@ -176,6 +176,10 @@ func (p *processes) Start(proc process) {
|
||||||
proc.startup.subREQHttpGet(proc)
|
proc.startup.subREQHttpGet(proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if proc.configuration.StartSubREQHttpGetScheduled {
|
||||||
|
proc.startup.subREQHttpGetScheduled(proc)
|
||||||
|
}
|
||||||
|
|
||||||
if proc.configuration.StartSubREQTailFile {
|
if proc.configuration.StartSubREQTailFile {
|
||||||
proc.startup.subREQTailFile(proc)
|
proc.startup.subREQTailFile(proc)
|
||||||
}
|
}
|
||||||
|
@ -228,6 +232,16 @@ func (s startup) subREQHttpGet(p process) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s startup) subREQHttpGetScheduled(p process) {
|
||||||
|
|
||||||
|
log.Printf("Starting Http Get Scheduled subscriber: %#v\n", p.node)
|
||||||
|
sub := newSubject(REQHttpGetScheduled, string(p.node))
|
||||||
|
proc := newProcess(p.ctx, s.metrics, p.natsConn, p.processes, p.toRingbufferCh, p.configuration, sub, processKindSubscriber, nil, s.Signatures)
|
||||||
|
|
||||||
|
go proc.spawnWorker(p.processes, p.natsConn)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s startup) pubREQHello(p process) {
|
func (s startup) pubREQHello(p process) {
|
||||||
log.Printf("Starting Hello Publisher: %#v\n", p.node)
|
log.Printf("Starting Hello Publisher: %#v\n", p.node)
|
||||||
|
|
||||||
|
|
159
requests.go
159
requests.go
|
@ -44,6 +44,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -118,6 +119,9 @@ const (
|
||||||
REQPong Method = "REQPong"
|
REQPong Method = "REQPong"
|
||||||
// Http Get
|
// Http Get
|
||||||
REQHttpGet Method = "REQHttpGet"
|
REQHttpGet Method = "REQHttpGet"
|
||||||
|
// Http Get Scheduled
|
||||||
|
// The second element of the MethodArgs slice holds the timer defined in seconds.
|
||||||
|
REQHttpGetScheduled Method = "REQHttpGetScheduled"
|
||||||
// Tail file
|
// Tail file
|
||||||
REQTailFile Method = "REQTailFile"
|
REQTailFile Method = "REQTailFile"
|
||||||
// Write to steward socket
|
// Write to steward socket
|
||||||
|
@ -193,6 +197,9 @@ func (m Method) GetMethodsAvailable() MethodsAvailable {
|
||||||
REQHttpGet: methodREQHttpGet{
|
REQHttpGet: methodREQHttpGet{
|
||||||
event: EventACK,
|
event: EventACK,
|
||||||
},
|
},
|
||||||
|
REQHttpGetScheduled: methodREQHttpGetScheduled{
|
||||||
|
event: EventACK,
|
||||||
|
},
|
||||||
REQTailFile: methodREQTailFile{
|
REQTailFile: methodREQTailFile{
|
||||||
event: EventACK,
|
event: EventACK,
|
||||||
},
|
},
|
||||||
|
@ -1391,7 +1398,7 @@ func (m methodREQHttpGet) handler(proc process, message Message, node string) ([
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
cancel()
|
cancel()
|
||||||
er := fmt.Errorf("error: methodREQHttpGet: not 200, where %#v, bailing out: %v", resp.StatusCode, message)
|
er := fmt.Errorf("error: methodREQHttpGet: not 200, were %#v, bailing out: %v", resp.StatusCode, message)
|
||||||
proc.processes.errorKernel.errSend(proc, message, er)
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1431,6 +1438,156 @@ func (m methodREQHttpGet) handler(proc process, message Message, node string) ([
|
||||||
return ackMsg, nil
|
return ackMsg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
type methodREQHttpGetScheduled struct {
|
||||||
|
event Event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m methodREQHttpGetScheduled) getKind() Event {
|
||||||
|
return m.event
|
||||||
|
}
|
||||||
|
|
||||||
|
// handler to do a Http Get Scheduled.
|
||||||
|
// The second element of the MethodArgs slice holds the timer defined in seconds.
|
||||||
|
func (m methodREQHttpGetScheduled) handler(proc process, message Message, node string) ([]byte, error) {
|
||||||
|
log.Printf("<--- REQHttpGetScheduled received from: %v, containing: %v", message.FromNode, message.Data)
|
||||||
|
|
||||||
|
proc.processes.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer proc.processes.wg.Done()
|
||||||
|
|
||||||
|
// --- Check and prepare the methodArgs
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(message.MethodArgs) < 3:
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGet: got <3 number methodArgs. Want URL, Schedule Interval in seconds, and the total time in minutes the scheduler should run for")
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
log.Printf("%v\n", er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
url := message.MethodArgs[0]
|
||||||
|
|
||||||
|
scheduleInterval, err := strconv.Atoi(message.MethodArgs[1])
|
||||||
|
if err != nil {
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGetScheduled: schedule interval value is not a valid int number defined as a string value seconds: %v, bailing out: %v", err, message.MethodArgs)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// schedulerTotalTime, err := strconv.Atoi(message.MethodArgs[2])
|
||||||
|
if err != nil {
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGetScheduled: scheduler total time value is not a valid int number defined as a string value minutes: %v, bailing out: %v", err, message.MethodArgs)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Prepare and start the scheduler.
|
||||||
|
|
||||||
|
outCh := make(chan []byte)
|
||||||
|
|
||||||
|
ticker := time.NewTicker(time.Second * time.Duration(scheduleInterval))
|
||||||
|
|
||||||
|
// Prepare a context that will be for the schedule as a whole.
|
||||||
|
// NB: Individual http get's will create their own context's
|
||||||
|
// derived from this one.
|
||||||
|
ctxScheduler, cancel := context.WithTimeout(proc.ctx, time.Second*60)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// Prepare the http request.
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: time.Second * time.Duration(message.MethodTimeout),
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
proc.processes.wg.Add(1)
|
||||||
|
|
||||||
|
// Get a context with the timeout specified in message.MethodTimeout
|
||||||
|
// for the individual http requests.
|
||||||
|
ctx, cancel := getContextForMethodTimeout(proc.ctx, message)
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGet: NewRequest failed: %v, error: %v", err, message.MethodArgs)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run each individual http get in it's own go routine, and
|
||||||
|
// deliver the result on the outCh.
|
||||||
|
go func() {
|
||||||
|
defer proc.processes.wg.Done()
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGet: client.Do failed: %v, error: %v", err, message.MethodArgs)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
cancel()
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGet: not 200, were %#v, error: %v", resp.StatusCode, message)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGet: io.ReadAll failed : %v, methodArgs: %v", err, message.MethodArgs)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
log.Printf("%v\n", er)
|
||||||
|
}
|
||||||
|
|
||||||
|
out := body
|
||||||
|
|
||||||
|
select {
|
||||||
|
case outCh <- out:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-ctxScheduler.Done():
|
||||||
|
// If the scheduler context is done then we also want to kill
|
||||||
|
// all running http request.
|
||||||
|
cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
case <-ctxScheduler.Done():
|
||||||
|
cancel()
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctxScheduler.Done():
|
||||||
|
fmt.Printf(" * DEBUG: <-ctxScheduler.Done()\n")
|
||||||
|
cancel()
|
||||||
|
er := fmt.Errorf("error: methodREQHttpGet: schedule context timed out: %v", message.MethodArgs)
|
||||||
|
proc.processes.errorKernel.errSend(proc, message, er)
|
||||||
|
return
|
||||||
|
case out := <-outCh:
|
||||||
|
// Prepare and queue for sending a new message with the output
|
||||||
|
// of the action executed.
|
||||||
|
newReplyMessage(proc, message, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}()
|
||||||
|
|
||||||
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
||||||
|
return ackMsg, nil
|
||||||
|
}
|
||||||
|
|
||||||
// --- methodREQTailFile
|
// --- methodREQTailFile
|
||||||
|
|
||||||
type methodREQTailFile struct {
|
type methodREQTailFile struct {
|
||||||
|
|
Loading…
Add table
Reference in a new issue