mirror of
https://github.com/nabbar/golib.git
synced 2025-10-22 15:29:39 +08:00
Package Status:
- Rework for the management of mandatory components to qualify the global status. - Added qualification to components: "should", "must", "one of". - These qualifications will influence the overall state but not the unitary state of each component. Package Socket: - Creation package to open and listen local unix file socket - Allow to specify a handler who's needing a conn instance as entry - Create a client sub package to allow negociate with the local unix file socket Package Shell: - adding sub package for command and command collection Package Monitor: - add function to expose monitor command for shell Package Config: - add function to expose monitor command for shell Package Network: - Add "IP" protocol Pakcage Httpcli: - Rework the construction of the client - Add capability to specify proxy url Package Cobra: - add function to add flag to global command like verbose or config Package Log: - fix seg fault when calling a nil instance - remove println in hookfile / hooksyslog
This commit is contained in:
@@ -43,19 +43,19 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/go-uuid"
|
lbuuid "github.com/hashicorp/go-uuid"
|
||||||
"github.com/nabbar/golib/aws"
|
libaws "github.com/nabbar/golib/aws"
|
||||||
"github.com/nabbar/golib/aws/configCustom"
|
awscfg "github.com/nabbar/golib/aws/configCustom"
|
||||||
"github.com/nabbar/golib/httpcli"
|
libhtc "github.com/nabbar/golib/httpcli"
|
||||||
"github.com/nabbar/golib/password"
|
libpwd "github.com/nabbar/golib/password"
|
||||||
libsiz "github.com/nabbar/golib/size"
|
libsiz "github.com/nabbar/golib/size"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cli aws.AWS
|
cli libaws.AWS
|
||||||
cfg aws.Config
|
cfg libaws.Config
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cnl context.CancelFunc
|
cnl context.CancelFunc
|
||||||
filename = "./config.json"
|
filename = "./config.json"
|
||||||
@@ -88,14 +88,15 @@ var _ = BeforeSuite(func() {
|
|||||||
Host: "localhost:" + strconv.Itoa(GetFreePort()),
|
Host: "localhost:" + strconv.Itoa(GetFreePort()),
|
||||||
}
|
}
|
||||||
|
|
||||||
accessKey = password.Generate(20)
|
accessKey = libpwd.Generate(20)
|
||||||
secretKey = password.Generate(64)
|
secretKey = libpwd.Generate(64)
|
||||||
)
|
)
|
||||||
|
|
||||||
htp = httpcli.GetClient(uri.Hostname())
|
htp, err = libhtc.GetClient(libhtc.GetTransport(false, false, false), true, libhtc.ClientTimeout30Sec)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(htp).NotTo(BeNil())
|
Expect(htp).NotTo(BeNil())
|
||||||
|
|
||||||
cfg = configCustom.NewConfig("", accessKey, secretKey, uri, "us-east-1")
|
cfg = awscfg.NewConfig("", accessKey, secretKey, uri, "us-east-1")
|
||||||
Expect(cfg).NotTo(BeNil())
|
Expect(cfg).NotTo(BeNil())
|
||||||
|
|
||||||
cfg.SetRegion("us-east-1")
|
cfg.SetRegion("us-east-1")
|
||||||
@@ -114,13 +115,13 @@ var _ = BeforeSuite(func() {
|
|||||||
println("Minio is waiting on : " + uri.Host)
|
println("Minio is waiting on : " + uri.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli, err = aws.New(ctx, cfg, htp)
|
cli, err = libaws.New(ctx, cfg, htp)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(cli).NotTo(BeNil())
|
Expect(cli).NotTo(BeNil())
|
||||||
|
|
||||||
cli.ForcePathStyle(ctx, true)
|
cli.ForcePathStyle(ctx, true)
|
||||||
|
|
||||||
name, err = uuid.GenerateUUID()
|
name, err = lbuuid.GenerateUUID()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(name).ToNot(BeEmpty())
|
Expect(name).ToNot(BeEmpty())
|
||||||
cli.Config().SetBucketName(name)
|
cli.Config().SetBucketName(name)
|
||||||
@@ -144,7 +145,7 @@ func loadConfig() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg, err = configCustom.NewConfigJsonUnmashal(cnfByt); err != nil {
|
if cfg, err = awscfg.NewConfigJsonUnmashal(cnfByt); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ package cobra
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
libver "github.com/nabbar/golib/version"
|
libver "github.com/nabbar/golib/version"
|
||||||
@@ -53,6 +54,30 @@ type Cobra interface {
|
|||||||
SetFlagConfig(persistent bool, flagVar *string) error
|
SetFlagConfig(persistent bool, flagVar *string) error
|
||||||
SetFlagVerbose(persistent bool, flagVar *int)
|
SetFlagVerbose(persistent bool, flagVar *int)
|
||||||
|
|
||||||
|
AddFlagString(persistent bool, p *string, name, shorthand string, value string, usage string)
|
||||||
|
AddFlagCount(persistent bool, p *int, name, shorthand string, usage string)
|
||||||
|
AddFlagBool(persistent bool, p *bool, name, shorthand string, value bool, usage string)
|
||||||
|
AddFlagDuration(persistent bool, p *time.Duration, name, shorthand string, value time.Duration, usage string)
|
||||||
|
AddFlagFloat32(persistent bool, p *float32, name, shorthand string, value float32, usage string)
|
||||||
|
AddFlagFloat64(persistent bool, p *float64, name, shorthand string, value float64, usage string)
|
||||||
|
AddFlagInt(persistent bool, p *int, name, shorthand string, value int, usage string)
|
||||||
|
AddFlagInt8(persistent bool, p *int8, name, shorthand string, value int8, usage string)
|
||||||
|
AddFlagInt16(persistent bool, p *int16, name, shorthand string, value int16, usage string)
|
||||||
|
AddFlagInt32(persistent bool, p *int32, name, shorthand string, value int32, usage string)
|
||||||
|
AddFlagInt32Slice(persistent bool, p *[]int32, name, shorthand string, value []int32, usage string)
|
||||||
|
AddFlagInt64(persistent bool, p *int64, name, shorthand string, value int64, usage string)
|
||||||
|
AddFlagInt64Slice(persistent bool, p *[]int64, name, shorthand string, value []int64, usage string)
|
||||||
|
AddFlagUint(persistent bool, p *uint, name, shorthand string, value uint, usage string)
|
||||||
|
AddFlagUintSlice(persistent bool, p *[]uint, name, shorthand string, value []uint, usage string)
|
||||||
|
AddFlagUint8(persistent bool, p *uint8, name, shorthand string, value uint8, usage string)
|
||||||
|
AddFlagUint16(persistent bool, p *uint16, name, shorthand string, value uint16, usage string)
|
||||||
|
AddFlagUint32(persistent bool, p *uint32, name, shorthand string, value uint32, usage string)
|
||||||
|
AddFlagUint64(persistent bool, p *uint64, name, shorthand string, value uint64, usage string)
|
||||||
|
AddFlagStringArray(persistent bool, p *[]string, name, shorthand string, value []string, usage string)
|
||||||
|
AddFlagStringToInt(persistent bool, p *map[string]int, name, shorthand string, value map[string]int, usage string)
|
||||||
|
AddFlagStringToInt64(persistent bool, p *map[string]int64, name, shorthand string, value map[string]int64, usage string)
|
||||||
|
AddFlagStringToString(persistent bool, p *map[string]string, name, shorthand string, value map[string]string, usage string)
|
||||||
|
|
||||||
NewCommand(cmd, short, long, useWithoutCmd, exampleWithoutCmd string) *spfcbr.Command
|
NewCommand(cmd, short, long, useWithoutCmd, exampleWithoutCmd string) *spfcbr.Command
|
||||||
AddCommand(subCmd ...*spfcbr.Command)
|
AddCommand(subCmd ...*spfcbr.Command)
|
||||||
|
|
||||||
|
185
cobra/model.go
185
cobra/model.go
@@ -32,6 +32,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
libver "github.com/nabbar/golib/version"
|
libver "github.com/nabbar/golib/version"
|
||||||
@@ -175,3 +176,187 @@ func (c *cobra) getPackageDescShort() string {
|
|||||||
func (c *cobra) getPackageDescLong() string {
|
func (c *cobra) getPackageDescLong() string {
|
||||||
return c.s.GetDescription()
|
return c.s.GetDescription()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagString(persistent bool, p *string, name, shorthand string, value string, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().StringVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().StringVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagCount(persistent bool, p *int, name, shorthand string, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().CountVarP(p, name, shorthand, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().CountVarP(p, name, shorthand, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagBool(persistent bool, p *bool, name, shorthand string, value bool, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().BoolVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().BoolVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagDuration(persistent bool, p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().DurationVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().DurationVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagFloat32(persistent bool, p *float32, name, shorthand string, value float32, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Float32VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Float32VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagFloat64(persistent bool, p *float64, name, shorthand string, value float64, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Float64VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Float64VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt(persistent bool, p *int, name, shorthand string, value int, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().IntVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().IntVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt8(persistent bool, p *int8, name, shorthand string, value int8, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Int8VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Int8VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt16(persistent bool, p *int16, name, shorthand string, value int16, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Int16VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Int16VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt32(persistent bool, p *int32, name, shorthand string, value int32, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Int32VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Int32VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt32Slice(persistent bool, p *[]int32, name, shorthand string, value []int32, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Int32SliceVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Int32SliceVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt64(persistent bool, p *int64, name, shorthand string, value int64, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Int64VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Int64VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagInt64Slice(persistent bool, p *[]int64, name, shorthand string, value []int64, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Int64SliceVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Int64SliceVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagUint(persistent bool, p *uint, name, shorthand string, value uint, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().UintVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().UintVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagUintSlice(persistent bool, p *[]uint, name, shorthand string, value []uint, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().UintSliceVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().UintSliceVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagUint8(persistent bool, p *uint8, name, shorthand string, value uint8, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Uint8VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Uint8VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagUint16(persistent bool, p *uint16, name, shorthand string, value uint16, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Uint16VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Uint16VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagUint32(persistent bool, p *uint32, name, shorthand string, value uint32, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Uint32VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Uint32VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagUint64(persistent bool, p *uint64, name, shorthand string, value uint64, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().Uint64VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().Uint64VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagStringArray(persistent bool, p *[]string, name, shorthand string, value []string, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().StringArrayVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().StringArrayVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagStringToInt(persistent bool, p *map[string]int, name, shorthand string, value map[string]int, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().StringToIntVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().StringToIntVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagStringToInt64(persistent bool, p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().StringToInt64VarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().StringToInt64VarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cobra) AddFlagStringToString(persistent bool, p *map[string]string, name, shorthand string, value map[string]string, usage string) {
|
||||||
|
if persistent {
|
||||||
|
c.c.PersistentFlags().StringToStringVarP(p, name, shorthand, value, usage)
|
||||||
|
} else {
|
||||||
|
c.c.Flags().StringToStringVarP(p, name, shorthand, value, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -32,13 +32,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"golang.org/x/exp/slices"
|
cfgcst "github.com/nabbar/golib/config/const"
|
||||||
|
|
||||||
_const "github.com/nabbar/golib/config/const"
|
|
||||||
|
|
||||||
cfgtps "github.com/nabbar/golib/config/types"
|
cfgtps "github.com/nabbar/golib/config/types"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
spfcbr "github.com/spf13/cobra"
|
spfcbr "github.com/spf13/cobra"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *configModel) ComponentHas(key string) bool {
|
func (c *configModel) ComponentHas(key string) bool {
|
||||||
@@ -184,17 +182,19 @@ func (c *configModel) ComponentReload() liberr.Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *configModel) ComponentStop() {
|
func (c *configModel) ComponentStop() {
|
||||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
lst := c.ComponentDependencies()
|
||||||
if v, k := val.(cfgtps.Component); !k {
|
|
||||||
c.cpt.Delete(key)
|
|
||||||
} else if v == nil {
|
|
||||||
c.cpt.Delete(key)
|
|
||||||
} else if v.IsStarted() {
|
|
||||||
v.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
for i := len(lst) - 1; i >= 0; i-- {
|
||||||
})
|
key := lst[i]
|
||||||
|
|
||||||
|
if len(key) < 1 {
|
||||||
|
continue
|
||||||
|
} else if cpt := c.ComponentGet(key); cpt == nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
cpt.Stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *configModel) ComponentIsRunning(atLeast bool) bool {
|
func (c *configModel) ComponentIsRunning(atLeast bool) bool {
|
||||||
@@ -300,12 +300,12 @@ func (c *configModel) DefaultConfig() io.Reader {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if p := v.DefaultConfig(_const.JSONIndent); len(p) > 0 {
|
if p := v.DefaultConfig(cfgcst.JSONIndent); len(p) > 0 {
|
||||||
if buffer.Len() > n {
|
if buffer.Len() > n {
|
||||||
buffer.WriteString(",")
|
buffer.WriteString(",")
|
||||||
buffer.WriteString("\n")
|
buffer.WriteString("\n")
|
||||||
}
|
}
|
||||||
buffer.WriteString(fmt.Sprintf("%s\"%s\": ", _const.JSONIndent, key))
|
buffer.WriteString(fmt.Sprintf("%s\"%s\": ", cfgcst.JSONIndent, key))
|
||||||
buffer.Write(p)
|
buffer.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ func (c *configModel) DefaultConfig() io.Reader {
|
|||||||
|
|
||||||
if err := json.Compact(cmp, buffer.Bytes()); err != nil {
|
if err := json.Compact(cmp, buffer.Bytes()); err != nil {
|
||||||
return buffer
|
return buffer
|
||||||
} else if err = json.Indent(ind, cmp.Bytes(), "", _const.JSONIndent); err != nil {
|
} else if err = json.Indent(ind, cmp.Bytes(), "", cfgcst.JSONIndent); err != nil {
|
||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,11 +33,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
|
||||||
|
|
||||||
cfgtps "github.com/nabbar/golib/config/types"
|
cfgtps "github.com/nabbar/golib/config/types"
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
libver "github.com/nabbar/golib/version"
|
libver "github.com/nabbar/golib/version"
|
||||||
libvpr "github.com/nabbar/golib/viper"
|
libvpr "github.com/nabbar/golib/viper"
|
||||||
)
|
)
|
||||||
@@ -123,6 +123,11 @@ type Config interface {
|
|||||||
*/
|
*/
|
||||||
cfgtps.ComponentList
|
cfgtps.ComponentList
|
||||||
cfgtps.ComponentMonitor
|
cfgtps.ComponentMonitor
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Section Shell Command : github.com/nabbar/golib/shell
|
||||||
|
*/
|
||||||
|
GetShellCommand() []shlcmd.Command
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
152
config/shell.go
Normal file
152
config/shell.go
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ShellCommandInfo() []shlcmd.CommandInfo {
|
||||||
|
var res = make([]shlcmd.CommandInfo, 0)
|
||||||
|
|
||||||
|
res = append(res, shlcmd.Info("list", "list all components"))
|
||||||
|
res = append(res, shlcmd.Info("start", "Starting components (leave args empty to start all components)"))
|
||||||
|
res = append(res, shlcmd.Info("stop", "Stopping components (leave args empty to start all components)"))
|
||||||
|
res = append(res, shlcmd.Info("restart", "Restarting (stop, start) components (leave args empty to restart all components)"))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *configModel) GetShellCommand() []shlcmd.Command {
|
||||||
|
var res = make([]shlcmd.Command, 0)
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("list", "list all components", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
for _, key := range c.ComponentDependencies() {
|
||||||
|
if len(key) < 1 {
|
||||||
|
continue
|
||||||
|
} else if cpt := c.ComponentGet(key); cpt == nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
_, _ = fmt.Fprintln(buf, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("start", "Starting components (leave args empty to start all components)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = c.ComponentDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, key := range list {
|
||||||
|
if len(key) < 1 {
|
||||||
|
continue
|
||||||
|
} else if cpt := c.ComponentGet(key); cpt == nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Starting component '%s'", key))
|
||||||
|
e := cpt.Start()
|
||||||
|
c.componentUpdate(key, cpt)
|
||||||
|
if e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
} else if !cpt.IsStarted() {
|
||||||
|
_, _ = fmt.Fprintln(err, fmt.Errorf("component is not started"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("stop", "Stopping components (leave args empty to start all components)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = c.ComponentDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(list) - 1; i >= 0; i-- {
|
||||||
|
key := list[i]
|
||||||
|
|
||||||
|
if len(key) < 1 {
|
||||||
|
continue
|
||||||
|
} else if cpt := c.ComponentGet(key); cpt == nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Stopping component '%s'", key))
|
||||||
|
cpt.Stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("restart", "Restarting (stop, start) components (leave args empty to restart all components)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = c.ComponentDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(list) - 1; i >= 0; i-- {
|
||||||
|
key := list[i]
|
||||||
|
|
||||||
|
if len(key) < 1 {
|
||||||
|
continue
|
||||||
|
} else if cpt := c.ComponentGet(key); cpt == nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Stopping component '%s'", key))
|
||||||
|
cpt.Stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, "")
|
||||||
|
|
||||||
|
for _, key := range list {
|
||||||
|
if len(key) < 1 {
|
||||||
|
continue
|
||||||
|
} else if cpt := c.ComponentGet(key); cpt == nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Starting component '%s'", key))
|
||||||
|
e := cpt.Start()
|
||||||
|
c.componentUpdate(key, cpt)
|
||||||
|
if e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
} else if !cpt.IsStarted() {
|
||||||
|
_, _ = fmt.Fprintln(err, fmt.Errorf("component is not started"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
@@ -60,8 +60,9 @@ const (
|
|||||||
MinPkgSMTPConfig = 3050
|
MinPkgSMTPConfig = 3050
|
||||||
MinPkgStatic = 3100
|
MinPkgStatic = 3100
|
||||||
MinPkgStatus = 3200
|
MinPkgStatus = 3200
|
||||||
MinPkgVersion = 3300
|
MinPkgSocket = 3300
|
||||||
MinPkgViper = 3400
|
MinPkgVersion = 3400
|
||||||
|
MinPkgViper = 3500
|
||||||
|
|
||||||
MinAvailable = 4000
|
MinAvailable = 4000
|
||||||
|
|
||||||
|
66
go.mod
66
go.mod
@@ -3,11 +3,11 @@ module github.com/nabbar/golib
|
|||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aws/aws-sdk-go-v2 v1.18.1
|
github.com/aws/aws-sdk-go-v2 v1.19.0
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.27
|
github.com/aws/aws-sdk-go-v2/config v1.18.28
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.26
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.27
|
||||||
github.com/aws/aws-sdk-go-v2/service/iam v1.21.0
|
github.com/aws/aws-sdk-go-v2/service/iam v1.21.1
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.36.0
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.37.0
|
||||||
github.com/bits-and-blooms/bitset v1.8.0
|
github.com/bits-and-blooms/bitset v1.8.0
|
||||||
github.com/c-bata/go-prompt v0.2.6
|
github.com/c-bata/go-prompt v0.2.6
|
||||||
github.com/fatih/color v1.15.0
|
github.com/fatih/color v1.15.0
|
||||||
@@ -28,11 +28,11 @@ require (
|
|||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/nats-io/jwt/v2 v2.4.1
|
github.com/nats-io/jwt/v2 v2.4.1
|
||||||
github.com/nats-io/nats-server/v2 v2.9.19
|
github.com/nats-io/nats-server/v2 v2.9.20
|
||||||
github.com/nats-io/nats.go v1.27.1
|
github.com/nats-io/nats.go v1.28.0
|
||||||
github.com/nutsdb/nutsdb v0.12.3
|
github.com/nutsdb/nutsdb v0.12.3
|
||||||
github.com/onsi/ginkgo/v2 v2.11.0
|
github.com/onsi/ginkgo/v2 v2.11.0
|
||||||
github.com/onsi/gomega v1.27.8
|
github.com/onsi/gomega v1.27.9
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/prometheus/client_golang v1.16.0
|
github.com/prometheus/client_golang v1.16.0
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||||
@@ -42,15 +42,15 @@ require (
|
|||||||
github.com/spf13/viper v1.16.0
|
github.com/spf13/viper v1.16.0
|
||||||
github.com/ugorji/go/codec v1.2.11
|
github.com/ugorji/go/codec v1.2.11
|
||||||
github.com/vbauerster/mpb/v5 v5.4.0
|
github.com/vbauerster/mpb/v5 v5.4.0
|
||||||
github.com/xanzy/go-gitlab v0.86.0
|
github.com/xanzy/go-gitlab v0.88.0
|
||||||
github.com/xhit/go-simple-mail v2.2.2+incompatible
|
github.com/xhit/go-simple-mail v2.2.2+incompatible
|
||||||
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235
|
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235
|
||||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
|
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0
|
||||||
golang.org/x/net v0.11.0
|
golang.org/x/net v0.12.0
|
||||||
golang.org/x/oauth2 v0.9.0
|
golang.org/x/oauth2 v0.10.0
|
||||||
golang.org/x/sync v0.3.0
|
golang.org/x/sync v0.3.0
|
||||||
golang.org/x/sys v0.10.0
|
golang.org/x/sys v0.10.0
|
||||||
golang.org/x/term v0.9.0
|
golang.org/x/term v0.10.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/clickhouse v0.5.1
|
gorm.io/driver/clickhouse v0.5.1
|
||||||
gorm.io/driver/mysql v1.5.1
|
gorm.io/driver/mysql v1.5.1
|
||||||
@@ -62,8 +62,8 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||||
github.com/ClickHouse/ch-go v0.57.0 // indirect
|
github.com/ClickHouse/ch-go v0.58.0 // indirect
|
||||||
github.com/ClickHouse/clickhouse-go/v2 v2.10.1 // indirect
|
github.com/ClickHouse/clickhouse-go/v2 v2.11.0 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||||
@@ -75,18 +75,18 @@ require (
|
|||||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||||
github.com/armon/go-metrics v0.4.1 // indirect
|
github.com/armon/go-metrics v0.4.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.27 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.30 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 // indirect
|
||||||
github.com/aws/smithy-go v1.13.5 // indirect
|
github.com/aws/smithy-go v1.13.5 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||||
@@ -118,7 +118,7 @@ require (
|
|||||||
github.com/google/btree v1.1.2 // indirect
|
github.com/google/btree v1.1.2 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
|
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/gorilla/css v1.0.0 // indirect
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
@@ -135,7 +135,7 @@ require (
|
|||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||||
github.com/jackc/pgx/v5 v5.4.1 // indirect
|
github.com/jackc/pgx/v5 v5.4.2 // indirect
|
||||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
@@ -153,7 +153,7 @@ require (
|
|||||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||||
github.com/mattn/go-tty v0.0.5 // indirect
|
github.com/mattn/go-tty v0.0.5 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/microsoft/go-mssqldb v1.3.0 // indirect
|
github.com/microsoft/go-mssqldb v1.4.0 // indirect
|
||||||
github.com/miekg/dns v1.1.55 // indirect
|
github.com/miekg/dns v1.1.55 // indirect
|
||||||
github.com/minio/highwayhash v1.0.2 // indirect
|
github.com/minio/highwayhash v1.0.2 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
@@ -163,8 +163,8 @@ require (
|
|||||||
github.com/nats-io/nkeys v0.4.4 // indirect
|
github.com/nats-io/nkeys v0.4.4 // indirect
|
||||||
github.com/nats-io/nuid v1.0.1 // indirect
|
github.com/nats-io/nuid v1.0.1 // indirect
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/paulmach/orb v0.9.2 // indirect
|
github.com/paulmach/orb v0.10.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pkg/term v1.2.0-beta.2 // indirect
|
github.com/pkg/term v1.2.0-beta.2 // indirect
|
||||||
@@ -193,11 +193,11 @@ require (
|
|||||||
go.opentelemetry.io/otel v1.16.0 // indirect
|
go.opentelemetry.io/otel v1.16.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||||
golang.org/x/arch v0.4.0 // indirect
|
golang.org/x/arch v0.4.0 // indirect
|
||||||
golang.org/x/crypto v0.10.0 // indirect
|
golang.org/x/crypto v0.11.0 // indirect
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
golang.org/x/text v0.11.0 // indirect
|
golang.org/x/text v0.11.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.10.0 // indirect
|
golang.org/x/tools v0.11.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.31.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
101
httpcli/cli.go
101
httpcli/cli.go
@@ -33,12 +33,10 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
libptc "github.com/nabbar/golib/network/protocol"
|
|
||||||
|
|
||||||
"golang.org/x/net/http2"
|
|
||||||
|
|
||||||
libtls "github.com/nabbar/golib/certificates"
|
libtls "github.com/nabbar/golib/certificates"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -53,78 +51,57 @@ const (
|
|||||||
|
|
||||||
type FctHttpClient func() *http.Client
|
type FctHttpClient func() *http.Client
|
||||||
|
|
||||||
func GetClient(serverName string) *http.Client {
|
func GetTransport(DisableKeepAlive, DisableCompression, ForceHTTP2 bool) *http.Transport {
|
||||||
c, e := GetClientTimeout(serverName, true, 0)
|
return &http.Transport{
|
||||||
|
|
||||||
if e != nil {
|
|
||||||
c, _ = GetClientTimeout(serverName, false, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetClientError(serverName string) (*http.Client, liberr.Error) {
|
|
||||||
return GetClientTimeout(serverName, true, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetClientTimeout(serverName string, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
|
||||||
dl := &net.Dialer{}
|
|
||||||
|
|
||||||
tr := &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
DialContext: dl.DialContext,
|
DialContext: nil,
|
||||||
DisableCompression: true,
|
DialTLSContext: nil,
|
||||||
//nolint #staticcheck
|
TLSClientConfig: nil,
|
||||||
TLSClientConfig: libtls.GetTLSConfig(serverName),
|
DisableKeepAlives: DisableKeepAlive,
|
||||||
|
DisableCompression: DisableCompression,
|
||||||
|
ForceAttemptHTTP2: ForceHTTP2,
|
||||||
}
|
}
|
||||||
|
|
||||||
return getclient(tr, http2Tr, GlobalTimeout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetClientCustom(tr *http.Transport, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
func SetTransportTLS(tr *http.Transport, tls libtls.TLSConfig, servername string) {
|
||||||
return getclient(tr, http2Tr, GlobalTimeout)
|
tr.TLSClientConfig = tls.TlsConfig(servername)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetClientTls(serverName string, tls libtls.TLSConfig, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
func SetTransportProxy(tr *http.Transport, proxyUrl *url.URL) {
|
||||||
dl := &net.Dialer{}
|
tr.Proxy = http.ProxyURL(proxyUrl)
|
||||||
|
|
||||||
tr := &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
|
||||||
DialContext: dl.DialContext,
|
|
||||||
DisableCompression: true,
|
|
||||||
//nolint #staticcheck
|
|
||||||
TLSClientConfig: tls.TlsConfig(serverName),
|
|
||||||
}
|
|
||||||
|
|
||||||
return getclient(tr, http2Tr, GlobalTimeout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetClientTlsForceIp(netw libptc.NetworkProtocol, ip string, serverName string, tls libtls.TLSConfig, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
func SetTransportDial(tr *http.Transport, forceIp bool, netw libptc.NetworkProtocol, ip, local string) {
|
||||||
u := &url.URL{
|
var (
|
||||||
Host: ip,
|
fctDial func(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
}
|
)
|
||||||
|
|
||||||
fctDial := func(ctx context.Context, network, address string) (net.Conn, error) {
|
if forceIp && len(local) > 0 {
|
||||||
dl := &net.Dialer{
|
u := &url.URL{
|
||||||
LocalAddr: &net.TCPAddr{
|
Host: local,
|
||||||
IP: net.ParseIP(u.Hostname()),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return dl.DialContext(ctx, netw.Code(), ip)
|
fctDial = func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
dl := &net.Dialer{
|
||||||
|
LocalAddr: &net.TCPAddr{
|
||||||
|
IP: net.ParseIP(u.Hostname()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return dl.DialContext(ctx, netw.Code(), ip)
|
||||||
|
}
|
||||||
|
} else if forceIp {
|
||||||
|
fctDial = func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
dl := &net.Dialer{}
|
||||||
|
return dl.DialContext(ctx, netw.Code(), ip)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dl := &net.Dialer{}
|
||||||
|
fctDial = dl.DialContext
|
||||||
}
|
}
|
||||||
|
|
||||||
tr := &http.Transport{
|
tr.DialContext = fctDial
|
||||||
Proxy: http.ProxyFromEnvironment,
|
|
||||||
DialContext: fctDial,
|
|
||||||
DisableCompression: true,
|
|
||||||
//nolint #staticcheck
|
|
||||||
TLSClientConfig: tls.TlsConfig(serverName),
|
|
||||||
}
|
|
||||||
|
|
||||||
return getclient(tr, http2Tr, GlobalTimeout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getclient(tr *http.Transport, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
func GetClient(tr *http.Transport, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
||||||
if http2Tr {
|
if http2Tr {
|
||||||
if e := http2.ConfigureTransport(tr); e != nil {
|
if e := http2.ConfigureTransport(tr); e != nil {
|
||||||
return nil, ErrorClientTransportHttp2.ErrorParent(e)
|
return nil, ErrorClientTransportHttp2.ErrorParent(e)
|
||||||
|
@@ -29,6 +29,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
|
||||||
libtls "github.com/nabbar/golib/certificates"
|
libtls "github.com/nabbar/golib/certificates"
|
||||||
"github.com/nabbar/golib/httpcli"
|
"github.com/nabbar/golib/httpcli"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
@@ -59,7 +61,7 @@ var _ = Describe("HttpCli", func() {
|
|||||||
},
|
},
|
||||||
ForceIP: httpcli.OptionForceIP{
|
ForceIP: httpcli.OptionForceIP{
|
||||||
Enable: true,
|
Enable: true,
|
||||||
Net: "tcp",
|
Net: libptc.NetworkTCP,
|
||||||
IP: "127.0.0.1:8080",
|
IP: "127.0.0.1:8080",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -31,23 +31,22 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
libptc "github.com/nabbar/golib/network/protocol"
|
libval "github.com/go-playground/validator/v10"
|
||||||
|
libtls "github.com/nabbar/golib/certificates"
|
||||||
cmptls "github.com/nabbar/golib/config/components/tls"
|
cmptls "github.com/nabbar/golib/config/components/tls"
|
||||||
cfgcst "github.com/nabbar/golib/config/const"
|
cfgcst "github.com/nabbar/golib/config/const"
|
||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
|
||||||
|
|
||||||
libtls "github.com/nabbar/golib/certificates"
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OptionForceIP struct {
|
type OptionForceIP struct {
|
||||||
Enable bool `json:"enable" yaml:"enable" toml:"enable" mapstructure:"enable"`
|
Enable bool `json:"enable" yaml:"enable" toml:"enable" mapstructure:"enable"`
|
||||||
Net string `json:"net,omitempty" yaml:"net,omitempty" toml:"net,omitempty" mapstructure:"net,omitempty"`
|
Net libptc.NetworkProtocol `json:"net,omitempty" yaml:"net,omitempty" toml:"net,omitempty" mapstructure:"net,omitempty"`
|
||||||
IP string `json:"ip,omitempty" yaml:"ip,omitempty" toml:"ip,omitempty" mapstructure:"ip,omitempty"`
|
IP string `json:"ip,omitempty" yaml:"ip,omitempty" toml:"ip,omitempty" mapstructure:"ip,omitempty"`
|
||||||
|
Local string `json:"local,omitempty" yaml:"local,omitempty" toml:"local,omitempty" mapstructure:"local,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionTLS struct {
|
type OptionTLS struct {
|
||||||
@@ -55,11 +54,19 @@ type OptionTLS struct {
|
|||||||
Config libtls.Config `json:"tls" yaml:"tls" toml:"tls" mapstructure:"tls"`
|
Config libtls.Config `json:"tls" yaml:"tls" toml:"tls" mapstructure:"tls"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OptionProxy struct {
|
||||||
|
Enable bool `json:"enable" yaml:"enable" toml:"enable" mapstructure:"enable"`
|
||||||
|
Endpoint *url.URL `json:"endpoint" yaml:"endpoint" toml:"endpoint" mapstructure:"endpoint"`
|
||||||
|
Username string `json:"username" yaml:"username" toml:"username" mapstructure:"username"`
|
||||||
|
Password string `json:"password" yaml:"password" toml:"password" mapstructure:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Timeout time.Duration `json:"timeout" yaml:"timeout" toml:"timeout" mapstructure:"timeout"`
|
Timeout time.Duration `json:"timeout" yaml:"timeout" toml:"timeout" mapstructure:"timeout"`
|
||||||
Http2 bool `json:"http2" yaml:"http2" toml:"http2" mapstructure:"http2"`
|
Http2 bool `json:"http2" yaml:"http2" toml:"http2" mapstructure:"http2"`
|
||||||
TLS OptionTLS `json:"tls" yaml:"tls" toml:"tls" mapstructure:"tls"`
|
TLS OptionTLS `json:"tls" yaml:"tls" toml:"tls" mapstructure:"tls"`
|
||||||
ForceIP OptionForceIP `json:"force_ip" yaml:"force_ip" toml:"force_ip" mapstructure:"force_ip"`
|
ForceIP OptionForceIP `json:"force_ip" yaml:"force_ip" toml:"force_ip" mapstructure:"force_ip"`
|
||||||
|
Proxy OptionProxy `json:"proxy" yaml:"proxy" toml:"proxy" mapstructure:"proxy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultConfig(indent string) []byte {
|
func DefaultConfig(indent string) []byte {
|
||||||
@@ -72,7 +79,14 @@ func DefaultConfig(indent string) []byte {
|
|||||||
"force_ip": {
|
"force_ip": {
|
||||||
"enable": false,
|
"enable": false,
|
||||||
"net":"tcp",
|
"net":"tcp",
|
||||||
"ip":"127.0.0.1:8080"
|
"ip":"127.0.0.1:8080",
|
||||||
|
"local":"127.0.0.1"
|
||||||
|
},
|
||||||
|
"proxy": {
|
||||||
|
"enable": false,
|
||||||
|
"endpoint":"http://example.com",
|
||||||
|
"username":"example",
|
||||||
|
"password":"example"
|
||||||
}
|
}
|
||||||
}`)
|
}`)
|
||||||
)
|
)
|
||||||
@@ -113,11 +127,47 @@ func (o Options) GetClient(def libtls.TLSConfig, servername string) (*http.Clien
|
|||||||
tls = t
|
tls = t
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.ForceIP.Enable {
|
var tr *http.Transport
|
||||||
return GetClientTlsForceIp(libptc.Parse(o.ForceIP.Net), o.ForceIP.IP, servername, tls, o.Http2, o.Timeout)
|
|
||||||
} else {
|
tr = GetTransport(false, false, o.Http2)
|
||||||
return GetClientTls(servername, tls, o.Http2, o.Timeout)
|
SetTransportTLS(tr, tls, "")
|
||||||
|
SetTransportDial(tr, o.ForceIP.Enable, o.ForceIP.Net, o.ForceIP.IP, o.ForceIP.Local)
|
||||||
|
|
||||||
|
if o.Proxy.Enable && o.Proxy.Endpoint != nil {
|
||||||
|
var edp *url.URL
|
||||||
|
|
||||||
|
edp = &url.URL{
|
||||||
|
Scheme: o.Proxy.Endpoint.Scheme,
|
||||||
|
Opaque: o.Proxy.Endpoint.Opaque,
|
||||||
|
User: nil,
|
||||||
|
Host: o.Proxy.Endpoint.Host,
|
||||||
|
Path: o.Proxy.Endpoint.Path,
|
||||||
|
RawPath: o.Proxy.Endpoint.RawPath,
|
||||||
|
OmitHost: o.Proxy.Endpoint.OmitHost,
|
||||||
|
ForceQuery: o.Proxy.Endpoint.ForceQuery,
|
||||||
|
RawQuery: o.Proxy.Endpoint.RawQuery,
|
||||||
|
Fragment: o.Proxy.Endpoint.Fragment,
|
||||||
|
RawFragment: o.Proxy.Endpoint.RawFragment,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(o.Proxy.Password) > 0 {
|
||||||
|
edp.User = url.UserPassword(o.Proxy.Username, o.Proxy.Password)
|
||||||
|
} else if len(o.Proxy.Username) > 0 {
|
||||||
|
edp.User = url.User(o.Proxy.Username)
|
||||||
|
} else if o.Proxy.Endpoint.User != nil {
|
||||||
|
if p, k := o.Proxy.Endpoint.User.Password(); k {
|
||||||
|
edp.User = url.UserPassword(o.Proxy.Endpoint.User.Username(), p)
|
||||||
|
} else {
|
||||||
|
edp.User = url.User(o.Proxy.Endpoint.User.Username())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if edp != nil && len(edp.String()) > 0 {
|
||||||
|
SetTransportProxy(tr, edp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GetClient(tr, o.Http2, o.Timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Options) _GetTLS(def libtls.TLSConfig) (libtls.TLSConfig, liberr.Error) {
|
func (o Options) _GetTLS(def libtls.TLSConfig) (libtls.TLSConfig, liberr.Error) {
|
||||||
|
@@ -47,7 +47,7 @@ func (o *hkf) Write(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *hkf) Close() error {
|
func (o *hkf) Close() error {
|
||||||
fmt.Printf("closing hook for log file '%s'\n", o.getFilepath())
|
//fmt.Printf("closing hook for log file '%s'\n", o.getFilepath())
|
||||||
|
|
||||||
o.d.Store(closeByte)
|
o.d.Store(closeByte)
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
@@ -121,7 +121,7 @@ func (o *hkf) Run(ctx context.Context) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
o.prepareChan()
|
o.prepareChan()
|
||||||
fmt.Printf("starting hook for log file '%s'\n", o.getFilepath())
|
//fmt.Printf("starting hook for log file '%s'\n", o.getFilepath())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@@ -61,7 +61,7 @@ func (o *hks) WriteSev(s SyslogSeverity, p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *hks) Close() error {
|
func (o *hks) Close() error {
|
||||||
fmt.Printf("closing hook for log syslog '%s'\n", o.getSyslogInfo())
|
//fmt.Printf("closing hook for log syslog '%s'\n", o.getSyslogInfo())
|
||||||
|
|
||||||
o.d.Store(closeByte)
|
o.d.Store(closeByte)
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
@@ -62,7 +62,7 @@ func (o *hks) Run(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
o.prepareChan()
|
o.prepareChan()
|
||||||
fmt.Printf("starting hook for log syslog '%s'\n", o.getSyslogInfo())
|
//fmt.Printf("starting hook for log syslog '%s'\n", o.getSyslogInfo())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@@ -37,34 +37,66 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (o *logger) Debug(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Debug(message string, data interface{}, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(loglvl.DebugLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.DebugLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Info(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Info(message string, data interface{}, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(loglvl.InfoLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.InfoLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Warning(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Warning(message string, data interface{}, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(loglvl.WarnLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.WarnLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Error(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Error(message string, data interface{}, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(loglvl.ErrorLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.ErrorLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Fatal(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Fatal(message string, data interface{}, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(loglvl.FatalLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.FatalLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Panic(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Panic(message string, data interface{}, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(loglvl.PanicLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.PanicLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) LogDetails(lvl loglvl.Level, message string, data interface{}, err []error, fields logfld.Fields, args ...interface{}) {
|
func (o *logger) LogDetails(lvl loglvl.Level, message string, data interface{}, err []error, fields logfld.Fields, args ...interface{}) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
o.newEntry(lvl, fmt.Sprintf(message, args...), err, fields, data).Log()
|
o.newEntry(lvl, fmt.Sprintf(message, args...), err, fields, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) CheckError(lvlKO, lvlOK loglvl.Level, message string, err ...error) bool {
|
func (o *logger) CheckError(lvlKO, lvlOK loglvl.Level, message string, err ...error) bool {
|
||||||
|
if o == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
ent := o.newEntry(lvlKO, message, err, nil, nil)
|
ent := o.newEntry(lvlKO, message, err, nil, nil)
|
||||||
return ent.Check(lvlOK)
|
return ent.Check(lvlOK)
|
||||||
}
|
}
|
||||||
@@ -79,21 +111,37 @@ func (o *logger) Access(remoteAddr, remoteUser string, localtime time.Time, late
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) newEntry(lvl loglvl.Level, message string, err []error, fields logfld.Fields, data interface{}) logent.Entry {
|
func (o *logger) newEntry(lvl loglvl.Level, message string, err []error, fields logfld.Fields, data interface{}) logent.Entry {
|
||||||
|
if o == nil {
|
||||||
|
return logent.New(loglvl.NilLevel)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
fct = o.getLogrus
|
||||||
ent = logent.New(lvl)
|
ent = logent.New(lvl)
|
||||||
frm = o.getCaller()
|
frm = o.getCaller()
|
||||||
|
stk = o.getStack()
|
||||||
|
fld = o.GetFields()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if o == nil {
|
||||||
|
return logent.New(loglvl.NilLevel)
|
||||||
|
} else if fld != nil {
|
||||||
|
ent.FieldSet(fld.FieldsClone(nil))
|
||||||
|
}
|
||||||
|
|
||||||
ent.ErrorSet(err)
|
ent.ErrorSet(err)
|
||||||
ent.FieldSet(o.GetFields().FieldsClone(nil))
|
|
||||||
ent.DataSet(data)
|
ent.DataSet(data)
|
||||||
ent.SetLogger(o.getLogrus)
|
ent.SetLogger(fct)
|
||||||
ent.SetEntryContext(time.Now(), o.getStack(), frm.Function, frm.File, uint64(frm.Line), message)
|
ent.SetEntryContext(time.Now(), stk, frm.Function, frm.File, uint64(frm.Line), message)
|
||||||
ent.FieldMerge(fields)
|
ent.FieldMerge(fields)
|
||||||
|
|
||||||
return ent
|
return ent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) newEntryClean(message string) logent.Entry {
|
func (o *logger) newEntryClean(message string) logent.Entry {
|
||||||
|
if o == nil {
|
||||||
|
return logent.New(loglvl.NilLevel)
|
||||||
|
}
|
||||||
|
|
||||||
return o.newEntry(loglvl.InfoLevel, message, nil, nil, nil).SetMessageOnly(true)
|
return o.newEntry(loglvl.InfoLevel, message, nil, nil, nil).SetMessageOnly(true)
|
||||||
}
|
}
|
||||||
|
@@ -32,9 +32,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
moninf "github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
monsts "github.com/nabbar/golib/monitor/status"
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
|
moninf "github.com/nabbar/golib/monitor/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@@ -30,11 +30,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
|
|
||||||
libprm "github.com/nabbar/golib/prometheus"
|
|
||||||
|
|
||||||
monsts "github.com/nabbar/golib/monitor/status"
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
|
libprm "github.com/nabbar/golib/prometheus"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (o *mon) RegisterMetricsName(names ...string) {
|
func (o *mon) RegisterMetricsName(names ...string) {
|
||||||
|
@@ -29,7 +29,7 @@ package monitor
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/nabbar/golib/monitor/types"
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fctMiddleWare func(m middleWare) error
|
type fctMiddleWare func(m middleWare) error
|
||||||
@@ -49,7 +49,7 @@ type mdl struct {
|
|||||||
mdl []fctMiddleWare
|
mdl []fctMiddleWare
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMiddleware(cfg *runCfg, fct types.HealthCheck) middleWare {
|
func newMiddleware(cfg *runCfg, fct montps.HealthCheck) middleWare {
|
||||||
o := &mdl{
|
o := &mdl{
|
||||||
ctx: nil,
|
ctx: nil,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
@@ -31,13 +31,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
|
||||||
|
|
||||||
libsrv "github.com/nabbar/golib/server"
|
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
libprm "github.com/nabbar/golib/prometheus"
|
libprm "github.com/nabbar/golib/prometheus"
|
||||||
|
libsrv "github.com/nabbar/golib/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pool interface {
|
type Pool interface {
|
||||||
|
218
monitor/pool/shell.go
Normal file
218
monitor/pool/shell.go
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ShellCommandInfo() []shlcmd.CommandInfo {
|
||||||
|
var res = make([]shlcmd.CommandInfo, 0)
|
||||||
|
|
||||||
|
res = append(res, shlcmd.Info("list", "Print the monitors' List"))
|
||||||
|
res = append(res, shlcmd.Info("info", "Print information about monitors (leave args empty to print info for all monitors)"))
|
||||||
|
res = append(res, shlcmd.Info("start", "Starting monitor (leave args empty to start all monitors)"))
|
||||||
|
res = append(res, shlcmd.Info("stop", "Stopping monitor (leave args empty to stop all monitors)"))
|
||||||
|
res = append(res, shlcmd.Info("restart", "Restarting monitor (leave args empty to restart all monitors)"))
|
||||||
|
res = append(res, shlcmd.Info("status", "Print status & message for monitor (leave args empty to print status of all monitors)"))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) GetShellCommand(ctx context.Context) []shlcmd.Command {
|
||||||
|
var res = make([]shlcmd.Command, 0)
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("list", "Print the monitors' List", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list = p.MonitorList()
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
_, _ = fmt.Fprintln(buf, list[i])
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("info", "Print information about monitors (leave args empty to print info for all monitors)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = p.MonitorList()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i]) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m := p.MonitorGet(list[i])
|
||||||
|
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
inf := m.InfoGet()
|
||||||
|
_, _ = fmt.Fprintln(buf, inf.Name())
|
||||||
|
for k, v := range inf.Info() {
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("\t%s: %s", k, v))
|
||||||
|
}
|
||||||
|
_, _ = fmt.Fprintln(buf, "")
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("start", "Starting monitor (leave args empty to start all monitors)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = p.MonitorList()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i]) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m := p.MonitorGet(list[i])
|
||||||
|
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Starting monitor '%s'", list[i]))
|
||||||
|
if e := m.Start(ctx); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Updating monitor '%s' on pool", list[i]))
|
||||||
|
if e := p.MonitorSet(m); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("stop", "Stopping monitor (leave args empty to stop all monitors)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = p.MonitorList()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i]) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m := p.MonitorGet(list[i])
|
||||||
|
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Stopping monitor '%s'", list[i]))
|
||||||
|
if e := m.Stop(ctx); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Updating monitor '%s' on pool", list[i]))
|
||||||
|
if e := p.MonitorSet(m); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("restart", "Restarting monitor (leave args empty to restart all monitors)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = p.MonitorList()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i]) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m := p.MonitorGet(list[i])
|
||||||
|
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Stopping monitor '%s'", list[i]))
|
||||||
|
if e := m.Stop(ctx); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Starting monitor '%s'", list[i]))
|
||||||
|
if e := m.Start(ctx); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("Updating monitor '%s' on pool", list[i]))
|
||||||
|
if e := p.MonitorSet(m); e != nil {
|
||||||
|
_, _ = fmt.Fprintln(err, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res = append(res, shlcmd.New("status", "Print status & message for monitor (leave args empty to print status of all monitors)", func(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
var list []string
|
||||||
|
if len(args) > 0 {
|
||||||
|
list = args
|
||||||
|
} else {
|
||||||
|
list = p.MonitorList()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i]) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m := p.MonitorGet(list[i])
|
||||||
|
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
s := m.Status()
|
||||||
|
|
||||||
|
if s == monsts.OK {
|
||||||
|
_, _ = fmt.Fprintln(buf, fmt.Sprintf("%s - %s", s.String(), list[i]))
|
||||||
|
} else {
|
||||||
|
_, _ = fmt.Fprintln(err, fmt.Sprintf("%s - %s: %s", s.String(), list[i], m.Message()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
@@ -32,11 +32,9 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
monsts "github.com/nabbar/golib/monitor/status"
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
libprm "github.com/nabbar/golib/prometheus"
|
libprm "github.com/nabbar/golib/prometheus"
|
||||||
libsrv "github.com/nabbar/golib/server"
|
libsrv "github.com/nabbar/golib/server"
|
||||||
|
@@ -27,20 +27,16 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding"
|
"encoding"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FuncPool func() Pool
|
type FuncPool func() Pool
|
||||||
|
|
||||||
type PoolStatus interface {
|
type PoolManage interface {
|
||||||
encoding.TextMarshaler
|
|
||||||
json.Marshaler
|
|
||||||
}
|
|
||||||
|
|
||||||
type Pool interface {
|
|
||||||
PoolStatus
|
|
||||||
|
|
||||||
MonitorAdd(mon Monitor) error
|
MonitorAdd(mon Monitor) error
|
||||||
MonitorGet(name string) Monitor
|
MonitorGet(name string) Monitor
|
||||||
MonitorSet(mon Monitor) error
|
MonitorSet(mon Monitor) error
|
||||||
@@ -48,3 +44,18 @@ type Pool interface {
|
|||||||
MonitorList() []string
|
MonitorList() []string
|
||||||
MonitorWalk(fct func(name string, val Monitor) bool, validName ...string)
|
MonitorWalk(fct func(name string, val Monitor) bool, validName ...string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PoolStatus interface {
|
||||||
|
encoding.TextMarshaler
|
||||||
|
json.Marshaler
|
||||||
|
PoolManage
|
||||||
|
}
|
||||||
|
|
||||||
|
type PoolShell interface {
|
||||||
|
GetShellCommand(ctx context.Context) []shlcmd.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pool interface {
|
||||||
|
PoolStatus
|
||||||
|
PoolShell
|
||||||
|
}
|
||||||
|
@@ -43,6 +43,9 @@ const (
|
|||||||
NetworkUDP
|
NetworkUDP
|
||||||
NetworkUDP4
|
NetworkUDP4
|
||||||
NetworkUDP6
|
NetworkUDP6
|
||||||
|
NetworkIP
|
||||||
|
NetworkIP4
|
||||||
|
NetworkIP6
|
||||||
)
|
)
|
||||||
|
|
||||||
func Parse(str string) NetworkProtocol {
|
func Parse(str string) NetworkProtocol {
|
||||||
@@ -66,7 +69,7 @@ func ParseBytes(p []byte) NetworkProtocol {
|
|||||||
return Parse(string(p))
|
return Parse(string(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
func SizeFromInt64(val int64) NetworkProtocol {
|
func ParseInt64(val int64) NetworkProtocol {
|
||||||
if val > int64(math.MaxUint8) {
|
if val > int64(math.MaxUint8) {
|
||||||
return NetworkProtocol(math.MaxUint8)
|
return NetworkProtocol(math.MaxUint8)
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,12 @@
|
|||||||
|
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
libmap "github.com/mitchellh/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
func (n NetworkProtocol) String() string {
|
func (n NetworkProtocol) String() string {
|
||||||
switch n {
|
switch n {
|
||||||
@@ -45,6 +50,12 @@ func (n NetworkProtocol) String() string {
|
|||||||
return "udp4"
|
return "udp4"
|
||||||
case NetworkUDP6:
|
case NetworkUDP6:
|
||||||
return "udp6"
|
return "udp6"
|
||||||
|
case NetworkIP:
|
||||||
|
return "ip"
|
||||||
|
case NetworkIP4:
|
||||||
|
return "ip4"
|
||||||
|
case NetworkIP6:
|
||||||
|
return "ip6"
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -53,3 +64,32 @@ func (n NetworkProtocol) String() string {
|
|||||||
func (n NetworkProtocol) Code() string {
|
func (n NetworkProtocol) Code() string {
|
||||||
return strings.ToLower(n.String())
|
return strings.ToLower(n.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ViperDecoderHook() libmap.DecodeHookFuncType {
|
||||||
|
return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
|
||||||
|
var (
|
||||||
|
z = NetworkProtocol(0)
|
||||||
|
t string
|
||||||
|
k bool
|
||||||
|
)
|
||||||
|
|
||||||
|
// Check if the data type matches the expected one
|
||||||
|
if from.Kind() != reflect.String {
|
||||||
|
return data, nil
|
||||||
|
} else if t, k = data.(string); !k {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the target type matches the expected one
|
||||||
|
if to != reflect.TypeOf(z) {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format/decode/parse the data and return the new value
|
||||||
|
if e := z.unmarshall([]byte(t)); e != nil {
|
||||||
|
return nil, e
|
||||||
|
} else {
|
||||||
|
return z, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -40,7 +40,7 @@ import (
|
|||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
libsh "github.com/nabbar/golib/shell"
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
libver "github.com/nabbar/golib/version"
|
libver "github.com/nabbar/golib/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ type NutsDB interface {
|
|||||||
|
|
||||||
Cluster() libclu.Cluster
|
Cluster() libclu.Cluster
|
||||||
Client(ctx context.Context, tickSync time.Duration) Client
|
Client(ctx context.Context, tickSync time.Duration) Client
|
||||||
ShellCommand(ctx func() context.Context, tickSync time.Duration) []libsh.Command
|
ShellCommand(ctx func() context.Context, tickSync time.Duration) []shlcmd.Command
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(c Config) NutsDB {
|
func New(c Config) NutsDB {
|
||||||
|
@@ -40,7 +40,7 @@ import (
|
|||||||
libclu "github.com/nabbar/golib/cluster"
|
libclu "github.com/nabbar/golib/cluster"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
libsh "github.com/nabbar/golib/shell"
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ndb struct {
|
type ndb struct {
|
||||||
@@ -265,9 +265,9 @@ func (n *ndb) Client(ctx context.Context, tickSync time.Duration) Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *ndb) ShellCommand(ctx func() context.Context, tickSync time.Duration) []libsh.Command {
|
func (n *ndb) ShellCommand(ctx func() context.Context, tickSync time.Duration) []shlcmd.Command {
|
||||||
var (
|
var (
|
||||||
res = make([]libsh.Command, 0)
|
res = make([]shlcmd.Command, 0)
|
||||||
cli func() Client
|
cli func() Client
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
libsh "github.com/nabbar/golib/shell"
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
"github.com/nutsdb/nutsdb"
|
"github.com/nutsdb/nutsdb"
|
||||||
"github.com/nutsdb/nutsdb/ds/zset"
|
"github.com/nutsdb/nutsdb/ds/zset"
|
||||||
)
|
)
|
||||||
@@ -45,7 +45,7 @@ type shellCommand struct {
|
|||||||
c func() Client
|
c func() Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func newShellCommand(code CmdCode, cli func() Client) libsh.Command {
|
func newShellCommand(code CmdCode, cli func() Client) shlcmd.Command {
|
||||||
if code == CmdUnknown {
|
if code == CmdUnknown {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
58
shell/command/interface.go
Normal file
58
shell/command/interface.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
|
package command
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
type FuncRun func(buf io.Writer, err io.Writer, args []string)
|
||||||
|
|
||||||
|
type CommandInfo interface {
|
||||||
|
Name() string
|
||||||
|
Describe() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Command interface {
|
||||||
|
CommandInfo
|
||||||
|
Run(buf io.Writer, err io.Writer, args []string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(name, desc string, fct FuncRun) Command {
|
||||||
|
return &model{
|
||||||
|
n: name,
|
||||||
|
d: desc,
|
||||||
|
r: fct,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info(name, desc string) CommandInfo {
|
||||||
|
return &model{
|
||||||
|
n: name,
|
||||||
|
d: desc,
|
||||||
|
r: nil,
|
||||||
|
}
|
||||||
|
}
|
62
shell/command/model.go
Normal file
62
shell/command/model.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type model struct {
|
||||||
|
n string
|
||||||
|
d string
|
||||||
|
r FuncRun
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) Name() string {
|
||||||
|
if o == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) Describe() string {
|
||||||
|
if o == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) Run(buf io.Writer, err io.Writer, args []string) {
|
||||||
|
if o == nil || o.r == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o.r(buf, err, args)
|
||||||
|
}
|
@@ -33,12 +33,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/c-bata/go-prompt"
|
libshl "github.com/c-bata/go-prompt"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *shell) RunPrompt(out, err io.Writer, opt ...prompt.Option) {
|
func (s *shell) RunPrompt(out, err io.Writer, opt ...libshl.Option) {
|
||||||
p := prompt.New(
|
p := libshl.New(
|
||||||
func(inputLine string) {
|
func(inputLine string) {
|
||||||
if out == nil {
|
if out == nil {
|
||||||
out = os.Stdout
|
out = os.Stdout
|
||||||
@@ -59,11 +60,11 @@ func (s *shell) RunPrompt(out, err io.Writer, opt ...prompt.Option) {
|
|||||||
|
|
||||||
s.Run(out, err, strings.Fields(inputLine))
|
s.Run(out, err, strings.Fields(inputLine))
|
||||||
},
|
},
|
||||||
func(document prompt.Document) []prompt.Suggest {
|
func(document libshl.Document) []libshl.Suggest {
|
||||||
var res = make([]prompt.Suggest, 0)
|
var res = make([]libshl.Suggest, 0)
|
||||||
|
|
||||||
_ = s.Walk(func(name string, item Command) (Command, liberr.Error) {
|
_ = s.Walk(func(name string, item shlcmd.Command) (shlcmd.Command, liberr.Error) {
|
||||||
res = append(res, prompt.Suggest{
|
res = append(res, libshl.Suggest{
|
||||||
Text: name,
|
Text: name,
|
||||||
Description: item.Describe(),
|
Description: item.Describe(),
|
||||||
})
|
})
|
||||||
|
@@ -30,30 +30,24 @@ package shell
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/c-bata/go-prompt"
|
libshl "github.com/c-bata/go-prompt"
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command interface {
|
|
||||||
Name() string
|
|
||||||
Describe() string
|
|
||||||
Run(buf io.Writer, err io.Writer, args []string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Shell interface {
|
type Shell interface {
|
||||||
Run(buf io.Writer, err io.Writer, args []string)
|
Run(buf io.Writer, err io.Writer, args []string)
|
||||||
Add(prefix string, cmd ...Command)
|
Add(prefix string, cmd ...shlcmd.Command)
|
||||||
Get(cmd string) []Command
|
Get(cmd string) []shlcmd.Command
|
||||||
Desc(cmd string) map[string]string
|
Desc(cmd string) map[string]string
|
||||||
Walk(fct func(name string, item Command) (Command, liberr.Error)) liberr.Error
|
Walk(fct func(name string, item shlcmd.Command) (shlcmd.Command, liberr.Error)) liberr.Error
|
||||||
|
|
||||||
//go prompt
|
//go prompt
|
||||||
RunPrompt(out, err io.Writer, opt ...prompt.Option)
|
RunPrompt(out, err io.Writer, opt ...libshl.Option)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() Shell {
|
func New() Shell {
|
||||||
return &shell{
|
return &shell{
|
||||||
c: make(map[string]Command),
|
c: make(map[string]shlcmd.Command),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,10 +32,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
shlcmd "github.com/nabbar/golib/shell/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shell struct {
|
type shell struct {
|
||||||
c map[string]Command
|
c map[string]shlcmd.Command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shell) Run(buf io.Writer, err io.Writer, args []string) {
|
func (s *shell) Run(buf io.Writer, err io.Writer, args []string) {
|
||||||
@@ -55,7 +56,7 @@ func (s *shell) Run(buf io.Writer, err io.Writer, args []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shell) Walk(fct func(name string, item Command) (Command, liberr.Error)) liberr.Error {
|
func (s *shell) Walk(fct func(name string, item shlcmd.Command) (shlcmd.Command, liberr.Error)) liberr.Error {
|
||||||
if fct == nil {
|
if fct == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -77,9 +78,9 @@ func (s *shell) Walk(fct func(name string, item Command) (Command, liberr.Error)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shell) Add(prefix string, cmd ...Command) {
|
func (s *shell) Add(prefix string, cmd ...shlcmd.Command) {
|
||||||
if len(s.c) == 0 {
|
if len(s.c) == 0 {
|
||||||
s.c = make(map[string]Command)
|
s.c = make(map[string]shlcmd.Command)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(cmd); i++ {
|
for i := 0; i < len(cmd); i++ {
|
||||||
@@ -98,10 +99,10 @@ func (s *shell) Add(prefix string, cmd ...Command) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shell) Get(cmd string) []Command {
|
func (s *shell) Get(cmd string) []shlcmd.Command {
|
||||||
var res = make([]Command, 0)
|
var res = make([]shlcmd.Command, 0)
|
||||||
|
|
||||||
_ = s.Walk(func(name string, item Command) (Command, liberr.Error) {
|
_ = s.Walk(func(name string, item shlcmd.Command) (shlcmd.Command, liberr.Error) {
|
||||||
if len(cmd) == 0 || name == cmd {
|
if len(cmd) == 0 || name == cmd {
|
||||||
res = append(res, item)
|
res = append(res, item)
|
||||||
}
|
}
|
||||||
@@ -115,7 +116,7 @@ func (s *shell) Get(cmd string) []Command {
|
|||||||
func (s *shell) Desc(cmd string) map[string]string {
|
func (s *shell) Desc(cmd string) map[string]string {
|
||||||
var res = make(map[string]string)
|
var res = make(map[string]string)
|
||||||
|
|
||||||
_ = s.Walk(func(name string, item Command) (Command, liberr.Error) {
|
_ = s.Walk(func(name string, item shlcmd.Command) (shlcmd.Command, liberr.Error) {
|
||||||
if len(cmd) == 0 || name == cmd {
|
if len(cmd) == 0 || name == cmd {
|
||||||
res[name] = item.Describe()
|
res[name] = item.Describe()
|
||||||
}
|
}
|
||||||
|
27
socket/client/ignore.go
Normal file
27
socket/client/ignore.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package client
|
55
socket/client/interface.go
Normal file
55
socket/client/interface.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
libsck "github.com/nabbar/golib/socket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client interface {
|
||||||
|
RegisterFuncError(f libsck.FuncError)
|
||||||
|
Connection(ctx context.Context, request io.Reader) (io.Reader, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(unixfile string) Client {
|
||||||
|
u := new(atomic.Value)
|
||||||
|
u.Store(unixfile)
|
||||||
|
|
||||||
|
return &clt{
|
||||||
|
u: u,
|
||||||
|
f: new(atomic.Value),
|
||||||
|
tr: new(atomic.Value),
|
||||||
|
tw: new(atomic.Value),
|
||||||
|
}
|
||||||
|
}
|
126
socket/client/model.go
Normal file
126
socket/client/model.go
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
libsck "github.com/nabbar/golib/socket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type clt struct {
|
||||||
|
u *atomic.Value // unixfile
|
||||||
|
f *atomic.Value // function error
|
||||||
|
tr *atomic.Value // connection read timeout
|
||||||
|
tw *atomic.Value // connection write timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *clt) RegisterFuncError(f libsck.FuncError) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o.f.Store(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *clt) fctError(e error) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v := o.f.Load()
|
||||||
|
if v != nil {
|
||||||
|
v.(libsck.FuncError)(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *clt) dial(ctx context.Context) (net.Conn, error) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, fmt.Errorf("invalid instance")
|
||||||
|
}
|
||||||
|
|
||||||
|
v := o.u.Load()
|
||||||
|
if v == nil {
|
||||||
|
return nil, fmt.Errorf("invalid unix file")
|
||||||
|
} else if _, e := os.Stat(v.(string)); e != nil {
|
||||||
|
return nil, e
|
||||||
|
} else {
|
||||||
|
d := net.Dialer{}
|
||||||
|
return d.DialContext(ctx, "unix", v.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *clt) Connection(ctx context.Context, request io.Reader) (io.Reader, error) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, fmt.Errorf("invalid instance")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
e error
|
||||||
|
|
||||||
|
cnn net.Conn
|
||||||
|
)
|
||||||
|
|
||||||
|
if cnn, e = o.dial(ctx); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
defer cnn.Close()
|
||||||
|
|
||||||
|
if request != nil {
|
||||||
|
if _, e = io.Copy(cnn, request); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if e = cnn.(*net.UnixConn).CloseWrite(); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf = bytes.NewBuffer(make([]byte, 0, 32*1024))
|
||||||
|
|
||||||
|
if _, e = io.Copy(buf, cnn); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = cnn.(*net.UnixConn).CloseRead()
|
||||||
|
|
||||||
|
return buf, nil
|
||||||
|
}
|
27
socket/ignore.go
Normal file
27
socket/ignore.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package socket
|
80
socket/inerface.go
Normal file
80
socket/inerface.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FuncError func(e error)
|
||||||
|
type Handler func(request io.Reader, response io.Writer)
|
||||||
|
|
||||||
|
type Server interface {
|
||||||
|
RegisterFuncError(f FuncError)
|
||||||
|
SetReadTimeout(d time.Duration)
|
||||||
|
SetWriteTimeout(d time.Duration)
|
||||||
|
|
||||||
|
Listen(ctx context.Context, unixFile string, perm os.FileMode)
|
||||||
|
Shutdown()
|
||||||
|
Done() <-chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(h Handler, sizeBuffRead, sizeBuffWrite int32) Server {
|
||||||
|
c := new(atomic.Value)
|
||||||
|
c.Store(make(chan []byte))
|
||||||
|
|
||||||
|
s := new(atomic.Value)
|
||||||
|
s.Store(make(chan struct{}))
|
||||||
|
|
||||||
|
f := new(atomic.Value)
|
||||||
|
f.Store(h)
|
||||||
|
|
||||||
|
sr := new(atomic.Int32)
|
||||||
|
sr.Store(sizeBuffRead)
|
||||||
|
|
||||||
|
sw := new(atomic.Int32)
|
||||||
|
sw.Store(sizeBuffWrite)
|
||||||
|
|
||||||
|
return &srv{
|
||||||
|
l: nil,
|
||||||
|
h: f,
|
||||||
|
c: c,
|
||||||
|
s: s,
|
||||||
|
f: new(atomic.Value),
|
||||||
|
tr: new(atomic.Value),
|
||||||
|
tw: new(atomic.Value),
|
||||||
|
sr: sr,
|
||||||
|
sw: sw,
|
||||||
|
}
|
||||||
|
}
|
202
socket/listener.go
Normal file
202
socket/listener.go
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *srv) timeoutRead() time.Time {
|
||||||
|
v := o.tr.Load()
|
||||||
|
if v != nil {
|
||||||
|
return time.Now().Add(v.(time.Duration))
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) timeoutWrite() time.Time {
|
||||||
|
v := o.tw.Load()
|
||||||
|
if v != nil {
|
||||||
|
return time.Now().Add(v.(time.Duration))
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) buffRead() *bytes.Buffer {
|
||||||
|
v := o.sr.Load()
|
||||||
|
if v > 0 {
|
||||||
|
return bytes.NewBuffer(make([]byte, 0, int(v)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.NewBuffer(make([]byte, 0, 32*1024))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) buffWrite() *bytes.Buffer {
|
||||||
|
v := o.sw.Load()
|
||||||
|
if v > 0 {
|
||||||
|
return bytes.NewBuffer(make([]byte, 0, int(v)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.NewBuffer(make([]byte, 0, 32*1024))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) checkFile(unixFile string) (string, error) {
|
||||||
|
if len(unixFile) < 1 {
|
||||||
|
return unixFile, fmt.Errorf("missing socket file path")
|
||||||
|
} else {
|
||||||
|
unixFile = filepath.Join(filepath.Dir(unixFile), filepath.Base(unixFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, e := os.Stat(unixFile); e != nil && !errors.Is(e, os.ErrNotExist) {
|
||||||
|
return unixFile, e
|
||||||
|
} else if e != nil {
|
||||||
|
return unixFile, nil
|
||||||
|
} else if e = os.Remove(unixFile); e != nil {
|
||||||
|
return unixFile, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return unixFile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) Listen(ctx context.Context, unixFile string, perm os.FileMode) {
|
||||||
|
var (
|
||||||
|
e error
|
||||||
|
i fs.FileInfo
|
||||||
|
l net.Listener
|
||||||
|
p = syscall.Umask(int(perm))
|
||||||
|
)
|
||||||
|
|
||||||
|
if unixFile, e = o.checkFile(unixFile); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
} else if l, e = net.Listen("unix", unixFile); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
} else if i, e = os.Stat(unixFile); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
syscall.Umask(p)
|
||||||
|
|
||||||
|
var fctClose = func() {
|
||||||
|
if l != nil {
|
||||||
|
o.fctError(l.Close())
|
||||||
|
}
|
||||||
|
|
||||||
|
if i, e = os.Stat(unixFile); e == nil {
|
||||||
|
o.fctError(os.Remove(unixFile))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer fctClose()
|
||||||
|
|
||||||
|
if i.Mode() != perm {
|
||||||
|
if e = os.Chmod(unixFile, perm); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept new connection or stop if context or shutdown trigger
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-o.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
// Accept an incoming connection.
|
||||||
|
if l == nil {
|
||||||
|
return
|
||||||
|
} else if co, ce := l.Accept(); ce != nil {
|
||||||
|
o.fctError(ce)
|
||||||
|
} else {
|
||||||
|
go o.Conn(co)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) Conn(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
var (
|
||||||
|
tr = o.timeoutRead()
|
||||||
|
tw = o.timeoutWrite()
|
||||||
|
br = o.buffRead()
|
||||||
|
bw = o.buffWrite()
|
||||||
|
)
|
||||||
|
|
||||||
|
if !tr.IsZero() {
|
||||||
|
if e := conn.SetReadDeadline(tr); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tw.IsZero() {
|
||||||
|
if e := conn.SetReadDeadline(tw); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, e := io.Copy(br, conn); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
} else if e = conn.(*net.UnixConn).CloseRead(); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if h := o.handler(); h != nil {
|
||||||
|
h(br, bw)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, e := io.Copy(conn, bw); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
} else if e = conn.(*net.UnixConn).CloseWrite(); e != nil {
|
||||||
|
o.fctError(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
132
socket/model.go
Normal file
132
socket/model.go
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultTimeoutRead = time.Second
|
||||||
|
defaultTimeoutWrite = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
closedChanStruct chan struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
closedChanStruct = make(chan struct{})
|
||||||
|
close(closedChanStruct)
|
||||||
|
}
|
||||||
|
|
||||||
|
type srv struct {
|
||||||
|
l net.Listener
|
||||||
|
|
||||||
|
h *atomic.Value // handler
|
||||||
|
c *atomic.Value // chan []byte
|
||||||
|
s *atomic.Value // chan struct{}
|
||||||
|
f *atomic.Value // function error
|
||||||
|
|
||||||
|
tr *atomic.Value // connection read timeout
|
||||||
|
tw *atomic.Value // connection write timeout
|
||||||
|
sr *atomic.Int32 // read buffer size
|
||||||
|
sw *atomic.Int32 // write buffer size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) Done() <-chan struct{} {
|
||||||
|
s := o.s.Load()
|
||||||
|
if s != nil {
|
||||||
|
return s.(chan struct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return closedChanStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) Shutdown() {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s := o.s.Load()
|
||||||
|
if s != nil {
|
||||||
|
o.s.Store(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) RegisterFuncError(f FuncError) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o.f.Store(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) SetReadTimeout(d time.Duration) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o.tr.Store(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) SetWriteTimeout(d time.Duration) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o.tw.Store(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) fctError(e error) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v := o.f.Load()
|
||||||
|
if v != nil {
|
||||||
|
v.(FuncError)(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *srv) handler() Handler {
|
||||||
|
if o == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := o.h.Load()
|
||||||
|
if v != nil {
|
||||||
|
return v.(Handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@@ -32,7 +32,9 @@ import (
|
|||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
libval "github.com/go-playground/validator/v10"
|
||||||
monsts "github.com/nabbar/golib/monitor/status"
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
"golang.org/x/exp/slices"
|
stsctr "github.com/nabbar/golib/status/control"
|
||||||
|
stslmd "github.com/nabbar/golib/status/listmandatory"
|
||||||
|
stsmdt "github.com/nabbar/golib/status/mandatory"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -42,7 +44,12 @@ const (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ReturnCode map[monsts.Status]int
|
ReturnCode map[monsts.Status]int
|
||||||
MandatoryComponent []string
|
MandatoryComponent stslmd.ListMandatory
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mandatory struct {
|
||||||
|
Mode stsctr.Mode
|
||||||
|
Keys []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Config) Validate() error {
|
func (o Config) Validate() error {
|
||||||
@@ -98,22 +105,37 @@ func (o *sts) cfgGetReturnCode(s monsts.Status) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *sts) cfgIsMandatory(name string) bool {
|
func (o *sts) cfgGetMandatory() stslmd.ListMandatory {
|
||||||
if i, l := o.x.Load(keyConfigMandatory); !l {
|
|
||||||
return false
|
|
||||||
} else if v, k := i.([]string); !k {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return slices.Contains(v, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *sts) cfgGetMandatory() []string {
|
|
||||||
if i, l := o.x.Load(keyConfigMandatory); !l {
|
if i, l := o.x.Load(keyConfigMandatory); !l {
|
||||||
return nil
|
return nil
|
||||||
} else if v, k := i.([]string); !k {
|
} else if v, k := i.(stslmd.ListMandatory); !k {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *sts) cfgGetMode(key string) stsctr.Mode {
|
||||||
|
if l := o.cfgGetMandatory(); len(l) < 1 {
|
||||||
|
return stsctr.Ignore
|
||||||
|
} else {
|
||||||
|
return l.GetMode(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *sts) cfgGetOne(key string) []string {
|
||||||
|
if l := o.cfgGetMandatory(); len(l) < 1 {
|
||||||
|
return make([]string, 0)
|
||||||
|
} else {
|
||||||
|
var r []string
|
||||||
|
l.Walk(func(m stsmdt.Mandatory) bool {
|
||||||
|
if m.KeyHas(key) {
|
||||||
|
r = m.KeyList()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
89
status/control/encode.go
Normal file
89
status/control/encode.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Mode) unmarshall(val []byte) error {
|
||||||
|
*c = ParseBytes(val)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Mode) MarshalJSON() ([]byte, error) {
|
||||||
|
t := c.String()
|
||||||
|
b := make([]byte, 0, len(t)+2)
|
||||||
|
b = append(b, '"')
|
||||||
|
b = append(b, []byte(t)...)
|
||||||
|
b = append(b, '"')
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Mode) UnmarshalJSON(bytes []byte) error {
|
||||||
|
return c.unmarshall(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Mode) MarshalYAML() (interface{}, error) {
|
||||||
|
return []byte(c.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Mode) UnmarshalYAML(value *yaml.Node) error {
|
||||||
|
return c.unmarshall([]byte(value.Value))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Mode) MarshalTOML() ([]byte, error) {
|
||||||
|
return []byte(c.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Mode) UnmarshalTOML(i interface{}) error {
|
||||||
|
if p, k := i.([]byte); k {
|
||||||
|
return c.unmarshall(p)
|
||||||
|
}
|
||||||
|
if p, k := i.(string); k {
|
||||||
|
return c.unmarshall([]byte(p))
|
||||||
|
}
|
||||||
|
return fmt.Errorf("size: value not in valid format")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Mode) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(c.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Mode) UnmarshalText(bytes []byte) error {
|
||||||
|
return c.unmarshall(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Mode) MarshalCBOR() ([]byte, error) {
|
||||||
|
return []byte(c.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Mode) UnmarshalCBOR(bytes []byte) error {
|
||||||
|
return c.unmarshall(bytes)
|
||||||
|
}
|
66
status/control/interface.go
Normal file
66
status/control/interface.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Mode uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Ignore Mode = iota
|
||||||
|
Should
|
||||||
|
Must
|
||||||
|
One
|
||||||
|
)
|
||||||
|
|
||||||
|
func Parse(s string) Mode {
|
||||||
|
switch {
|
||||||
|
case strings.EqualFold(Must.Code(), s):
|
||||||
|
return Must
|
||||||
|
case strings.EqualFold(One.Code(), s):
|
||||||
|
return One
|
||||||
|
case strings.EqualFold(Should.Code(), s):
|
||||||
|
return Should
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseBytes(p []byte) Mode {
|
||||||
|
return Parse(string(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseInt64(val int64) Mode {
|
||||||
|
if val > int64(math.MaxUint8) {
|
||||||
|
return Mode(math.MaxUint8)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Mode(uint8(val))
|
||||||
|
}
|
80
status/control/model.go
Normal file
80
status/control/model.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
libmap "github.com/mitchellh/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c Mode) String() string {
|
||||||
|
switch c {
|
||||||
|
case Must:
|
||||||
|
return "Must"
|
||||||
|
case One:
|
||||||
|
return "One"
|
||||||
|
case Should:
|
||||||
|
return "Should"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Mode) Code() string {
|
||||||
|
return strings.ToLower(c.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func ViperDecoderHook() libmap.DecodeHookFuncType {
|
||||||
|
return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
|
||||||
|
var (
|
||||||
|
z = Mode(0)
|
||||||
|
t string
|
||||||
|
k bool
|
||||||
|
)
|
||||||
|
|
||||||
|
// Check if the data type matches the expected one
|
||||||
|
if from.Kind() != reflect.String {
|
||||||
|
return data, nil
|
||||||
|
} else if t, k = data.(string); !k {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the target type matches the expected one
|
||||||
|
if to != reflect.TypeOf(z) {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format/decode/parse the data and return the new value
|
||||||
|
if e := z.unmarshall([]byte(t)); e != nil {
|
||||||
|
return nil, e
|
||||||
|
} else {
|
||||||
|
return z, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -35,12 +35,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
monpol "github.com/nabbar/golib/monitor/pool"
|
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/render"
|
ginrdr "github.com/gin-gonic/gin/render"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
monpol "github.com/nabbar/golib/monitor/pool"
|
||||||
monsts "github.com/nabbar/golib/monitor/status"
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
)
|
)
|
||||||
@@ -88,7 +86,7 @@ func (e *encodeModel) GinRender(c *ginsdk.Context, isText bool, isShort bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isText {
|
if isText {
|
||||||
c.Render(e.code, render.Data{
|
c.Render(e.code, ginrdr.Data{
|
||||||
ContentType: ginsdk.MIMEPlain,
|
ContentType: ginsdk.MIMEPlain,
|
||||||
Data: e.Bytes(),
|
Data: e.Bytes(),
|
||||||
})
|
})
|
||||||
|
@@ -31,15 +31,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
|
||||||
|
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
|
||||||
|
|
||||||
libver "github.com/nabbar/golib/version"
|
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
|
libver "github.com/nabbar/golib/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Route interface {
|
type Route interface {
|
||||||
@@ -54,7 +50,7 @@ type Info interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Pool interface {
|
type Pool interface {
|
||||||
montps.Pool
|
montps.PoolStatus
|
||||||
RegisterPool(fct montps.FuncPool)
|
RegisterPool(fct montps.FuncPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
status/listmandatory/interface.go
Normal file
37
status/listmandatory/interface.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package listmandatory
|
||||||
|
|
||||||
|
import stsmdt "github.com/nabbar/golib/status/mandatory"
|
||||||
|
|
||||||
|
type ListMandatory []stsmdt.Mandatory
|
||||||
|
|
||||||
|
func New(m ...stsmdt.Mandatory) ListMandatory {
|
||||||
|
res := make([]stsmdt.Mandatory, 0)
|
||||||
|
copy(res, m)
|
||||||
|
return res
|
||||||
|
}
|
126
status/listmandatory/model.go
Normal file
126
status/listmandatory/model.go
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package listmandatory
|
||||||
|
|
||||||
|
import (
|
||||||
|
stsctr "github.com/nabbar/golib/status/control"
|
||||||
|
stsmdt "github.com/nabbar/golib/status/mandatory"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l *ListMandatory) Walk(fct func(m stsmdt.Mandatory) bool) {
|
||||||
|
if l == nil {
|
||||||
|
return
|
||||||
|
} else if len(*l) < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
k bool
|
||||||
|
m stsmdt.Mandatory
|
||||||
|
n = *l
|
||||||
|
)
|
||||||
|
|
||||||
|
for i := range n {
|
||||||
|
m = n[i]
|
||||||
|
k = fct(m)
|
||||||
|
n[i] = m
|
||||||
|
|
||||||
|
if !k {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*l = n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *ListMandatory) Add(m ...stsmdt.Mandatory) {
|
||||||
|
if l == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var n = *l
|
||||||
|
|
||||||
|
if len(n) < 1 {
|
||||||
|
n = make([]stsmdt.Mandatory, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
*l = append(n, m...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *ListMandatory) Del(m stsmdt.Mandatory) {
|
||||||
|
if l == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
n = *l
|
||||||
|
r = make([]stsmdt.Mandatory, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(n) < 1 {
|
||||||
|
*l = make([]stsmdt.Mandatory, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range n {
|
||||||
|
if n[i] != m {
|
||||||
|
r = append(r, n[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*l = r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l ListMandatory) GetMode(key string) stsctr.Mode {
|
||||||
|
if len(l) < 1 {
|
||||||
|
return stsctr.Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range l {
|
||||||
|
if l[i].KeyHas(key) {
|
||||||
|
return l[i].GetMode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stsctr.Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *ListMandatory) SetMode(key string, mod stsctr.Mode) {
|
||||||
|
if len(*l) < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var n = *l
|
||||||
|
|
||||||
|
for i := range n {
|
||||||
|
if n[i].KeyHas(key) {
|
||||||
|
n[i].SetMode(mod)
|
||||||
|
*l = n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
status/mandatory/interface.go
Normal file
56
status/mandatory/interface.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mandatory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
stsctr "github.com/nabbar/golib/status/control"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Mandatory interface {
|
||||||
|
SetMode(m stsctr.Mode)
|
||||||
|
GetMode() stsctr.Mode
|
||||||
|
|
||||||
|
KeyHas(key string) bool
|
||||||
|
KeyAdd(keys ...string)
|
||||||
|
KeyDel(keys ...string)
|
||||||
|
KeyList() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() Mandatory {
|
||||||
|
m := new(atomic.Value)
|
||||||
|
m.Store(stsctr.Ignore)
|
||||||
|
|
||||||
|
k := new(atomic.Value)
|
||||||
|
k.Store(make([]string, 0))
|
||||||
|
|
||||||
|
return &model{
|
||||||
|
Mode: m,
|
||||||
|
Keys: k,
|
||||||
|
}
|
||||||
|
}
|
135
status/mandatory/model.go
Normal file
135
status/mandatory/model.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mandatory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
stsctr "github.com/nabbar/golib/status/control"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
|
)
|
||||||
|
|
||||||
|
type model struct {
|
||||||
|
Mode *atomic.Value
|
||||||
|
Keys *atomic.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) SetMode(m stsctr.Mode) {
|
||||||
|
o.Mode.Store(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) GetMode() stsctr.Mode {
|
||||||
|
m := o.Mode.Load()
|
||||||
|
|
||||||
|
if m != nil {
|
||||||
|
return m.(stsctr.Mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stsctr.Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) KeyHas(key string) bool {
|
||||||
|
i := o.Keys.Load()
|
||||||
|
|
||||||
|
if i == nil {
|
||||||
|
return false
|
||||||
|
} else if l, k := i.([]string); !k {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return slices.Contains(l, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) KeyAdd(keys ...string) {
|
||||||
|
var (
|
||||||
|
i any
|
||||||
|
k bool
|
||||||
|
l []string
|
||||||
|
)
|
||||||
|
|
||||||
|
i = o.Keys.Load()
|
||||||
|
|
||||||
|
if i == nil {
|
||||||
|
l = make([]string, 0)
|
||||||
|
} else if l, k = i.([]string); !k {
|
||||||
|
l = make([]string, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, key := range keys {
|
||||||
|
if !slices.Contains(l, key) {
|
||||||
|
l = append(l, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Keys.Store(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) KeyDel(keys ...string) {
|
||||||
|
var (
|
||||||
|
i any
|
||||||
|
k bool
|
||||||
|
l []string
|
||||||
|
)
|
||||||
|
|
||||||
|
i = o.Keys.Load()
|
||||||
|
|
||||||
|
if i == nil {
|
||||||
|
o.Keys.Store(make([]string, 0))
|
||||||
|
return
|
||||||
|
} else if l, k = i.([]string); !k {
|
||||||
|
o.Keys.Store(make([]string, 0))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var res = make([]string, 0)
|
||||||
|
|
||||||
|
for _, key := range l {
|
||||||
|
if !slices.Contains(keys, key) {
|
||||||
|
res = append(res, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Keys.Store(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *model) KeyList() []string {
|
||||||
|
var (
|
||||||
|
i any
|
||||||
|
k bool
|
||||||
|
l []string
|
||||||
|
)
|
||||||
|
|
||||||
|
i = o.Keys.Load()
|
||||||
|
|
||||||
|
if i == nil {
|
||||||
|
return make([]string, 0)
|
||||||
|
} else if l, k = i.([]string); !k {
|
||||||
|
return make([]string, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return slices.Clone(l)
|
||||||
|
}
|
@@ -30,12 +30,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
|
||||||
|
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
monsts "github.com/nabbar/golib/monitor/status"
|
monsts "github.com/nabbar/golib/monitor/status"
|
||||||
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
|
stsctr "github.com/nabbar/golib/status/control"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -74,28 +73,60 @@ func (o *sts) IsHealthy(name ...string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *sts) getStatus(keys ...string) (monsts.Status, string) {
|
func (o *sts) getStatus(keys ...string) (monsts.Status, string) {
|
||||||
if len(keys) < 1 {
|
stt := monsts.OK
|
||||||
keys = o.cfgGetMandatory()
|
msg := ""
|
||||||
}
|
ign := make([]string, 0)
|
||||||
|
|
||||||
o.m.RLock()
|
|
||||||
defer o.m.RUnlock()
|
|
||||||
|
|
||||||
s := monsts.OK
|
|
||||||
m := ""
|
|
||||||
|
|
||||||
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
||||||
if !slices.Contains(keys, name) {
|
if len(keys) > 0 && !slices.Contains(keys, name) {
|
||||||
|
return true
|
||||||
|
} else if len(ign) > 0 && slices.Contains(ign, name) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := val.Status(); s > v {
|
v := val.Status()
|
||||||
s = v
|
|
||||||
m = val.Message()
|
if c := o.cfgGetMode(name); c == stsctr.Ignore {
|
||||||
|
return true
|
||||||
|
} else if c == stsctr.Should && v < monsts.Warn {
|
||||||
|
if stt > monsts.Warn {
|
||||||
|
stt = monsts.Warn
|
||||||
|
msg = val.Message()
|
||||||
|
}
|
||||||
|
} else if c == stsctr.One {
|
||||||
|
lst := o.cfgGetOne(name)
|
||||||
|
sta := monsts.KO
|
||||||
|
res := ""
|
||||||
|
|
||||||
|
o.MonitorWalk(func(nme string, val montps.Monitor) bool {
|
||||||
|
if !slices.Contains(lst, nme) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
ign = append(ign, nme)
|
||||||
|
|
||||||
|
w := val.Status()
|
||||||
|
|
||||||
|
if w > sta {
|
||||||
|
sta = w
|
||||||
|
} else if w == sta && len(res) < 1 {
|
||||||
|
res = val.Message()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if stt > sta {
|
||||||
|
stt = sta
|
||||||
|
msg = res
|
||||||
|
}
|
||||||
|
} else if stt > v {
|
||||||
|
stt = v
|
||||||
|
msg = val.Message()
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
return s, m
|
return stt, msg
|
||||||
}
|
}
|
||||||
|
@@ -31,9 +31,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Reference in New Issue
Block a user