From 8a26ad3e3f2f56b59f75841a15028a99ae147233 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 25 Jun 2020 11:05:29 +0200 Subject: [PATCH] entrypoint/: configure Icinga Web 2 --- entrypoint/go.mod | 6 +++ entrypoint/go.sum | 17 ++++++++ entrypoint/main.go | 106 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 entrypoint/go.sum diff --git a/entrypoint/go.mod b/entrypoint/go.mod index f4829d3..01e2f5a 100644 --- a/entrypoint/go.mod +++ b/entrypoint/go.mod @@ -1,3 +1,9 @@ module entrypoint go 1.14 + +require ( + github.com/go-ini/ini v1.57.0 + github.com/smartystreets/goconvey v1.6.4 // indirect + gopkg.in/ini.v1 v1.57.0 // indirect +) diff --git a/entrypoint/go.sum b/entrypoint/go.sum new file mode 100644 index 0000000..e195b2d --- /dev/null +++ b/entrypoint/go.sum @@ -0,0 +1,17 @@ +github.com/go-ini/ini v1.57.0 h1:Qwzj3wZQW+Plax5Ntj+GYe07DfGj1OH+aL1nMTMaNow= +github.com/go-ini/ini v1.57.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= +gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/entrypoint/main.go b/entrypoint/main.go index 9d432cd..40de1b6 100644 --- a/entrypoint/main.go +++ b/entrypoint/main.go @@ -3,13 +3,22 @@ package main import ( "bufio" "fmt" + "github.com/go-ini/ini" + "io/ioutil" "os" "os/exec" + "path" "path/filepath" + "strings" "syscall" "time" ) +const confDir = "/data/etc/icingaweb2" +const dirMode = 0750 + +var enModsDir = path.Join(confDir, "enabledModules") + func main() { if err := entrypoint(); err != nil { logf("crit", "%s", err.Error()) @@ -26,10 +35,103 @@ func entrypoint() error { if os.Getpid() == 1 { logf("info", "Initializing /data as we're the init process") - logf("debug", `Creating "/data/etc/icingaweb2"`) - if errMA := os.MkdirAll("/data/etc/icingaweb2", 0750); errMA != nil { + logf("debug", "Creating %#v", enModsDir) + if errMA := os.MkdirAll(enModsDir, dirMode); errMA != nil { return errMA } + + logf("debug", "Translating env vars to .ini config") + + cfgs := map[string]*ini.File{} + var enabledModules map[string]struct{} = nil + + EnvVars: + for _, env := range os.Environ() { + if kv := strings.SplitN(env, "=", 2); len(kv) == 2 { + if strings.HasPrefix(kv[0], "icingaweb") { + if kv[0] = strings.TrimPrefix(kv[0], "icingaweb"); len(kv[0]) > 0 { + directive := strings.Split(kv[0][1:], kv[0][:1]) + for _, component := range directive { + if component == "" { + continue EnvVars + } + } + + if len(directive) == 1 { + if directive[0] == "enabledModules" { + if enabledModules == nil { + enabledModules = map[string]struct{}{} + } + + for _, mod := range strings.Split(kv[1], ",") { + if mod = strings.TrimSpace(mod); mod != "" { + enabledModules[mod] = struct{}{} + } + } + } + } else if len(directive) >= 3 { + file := path.Join(directive[:len(directive)-2]...) + cfg, ok := cfgs[file] + + if !ok { + cfg = ini.Empty() + cfgs[file] = cfg + } + + _, errNK := cfg.Section(directive[len(directive)-2]).NewKey( + strings.ToLower(directive[len(directive)-1]), kv[1], + ) + if errNK != nil { + return errNK + } + } + } + } + } + } + + for file, cfg := range cfgs { + file = path.Join(confDir, file+".ini") + logf("trace1", "Writing %#v", file) + + if errMA := os.MkdirAll(path.Dir(file), dirMode); errMA != nil { + return errMA + } + + if errST := cfg.SaveTo(file); errST != nil { + return errST + } + } + + if enabledModules != nil { + logf("debug", "Enabling/disabling modules") + + mods, errRD := ioutil.ReadDir(enModsDir) + if errRD != nil { + return errRD + } + + for _, mod := range mods { + mod := mod.Name() + if _, ok := enabledModules[mod]; ok { + delete(enabledModules, mod) + } else { + logf("trace1", "Disabling module %#v", mod) + if errRm := os.Remove(path.Join(enModsDir, mod)); errRm != nil { + return errRm + } + } + } + + for mod := range enabledModules { + logf("trace1", "Enabling module %#v", mod) + + errSl := os.Symlink(path.Join("/usr/share/icingaweb2/modules", mod), path.Join(enModsDir, mod)) + if errSl != nil { + return errSl + } + } + } } path := os.Args[1]