Try 05
This commit is contained in:
parent
983939046d
commit
eb50773656
6
Makefile
6
Makefile
|
@ -2,10 +2,10 @@ LINT_ARGS ?= ./...
|
||||||
DESTDIR ?= "/usr/local"
|
DESTDIR ?= "/usr/local"
|
||||||
|
|
||||||
bin:
|
bin:
|
||||||
GOOS=linux go build -o bin/templater-linux cmd/templater/main.go
|
GOOS=linux CGO_ENABLED=0 go build -o bin/templater-linux cmd/templater/main.go
|
||||||
GOOS=linux go build -o bin/bootstraper-linux cmd/bootstraper/main.go
|
GOOS=linux CGO_ENABLED=0 go build -o bin/bootstraper-linux cmd/bootstraper/main.go
|
||||||
upx bin/templater-linux
|
upx bin/templater-linux
|
||||||
upx bin/templaster-server
|
upx bin/bootstraper-linux
|
||||||
|
|
||||||
install:
|
install:
|
||||||
cp bin/templater-linux $(DESTDIR)/bin/templater
|
cp bin/templater-linux $(DESTDIR)/bin/templater
|
||||||
|
|
10
api/main.go
10
api/main.go
|
@ -1,9 +1,6 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"forge.cadoles.com/pcaseiro/templatefile/pkg/templater"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +10,12 @@ type Template struct {
|
||||||
Config string
|
Config string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Generate(c *gin.Context) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
func Generate(c *gin.Context) {
|
func Generate(c *gin.Context) {
|
||||||
var template Template
|
var template Template
|
||||||
|
|
||||||
|
@ -42,3 +45,4 @@ func Generate(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
{
|
{
|
||||||
"Name": "LokiStack",
|
"Name": "LokiStack",
|
||||||
"Global": {
|
"Global": {
|
||||||
"Vars": {
|
"Vars": {},
|
||||||
"EnableLoki": true,
|
|
||||||
"EnableGrafana": false,
|
|
||||||
"EnablePrometheus" : false
|
|
||||||
},
|
|
||||||
"ConfigFiles": [
|
"ConfigFiles": [
|
||||||
{
|
{
|
||||||
"destination": "/etc/hosts",
|
"destination": "/etc/hosts",
|
||||||
|
@ -18,7 +14,6 @@
|
||||||
},
|
},
|
||||||
"Services": {
|
"Services": {
|
||||||
"Loki": {
|
"Loki": {
|
||||||
"EnabledBy": { "var": "EnableLoki", "value": true },
|
|
||||||
"ConfigFiles": [
|
"ConfigFiles": [
|
||||||
{
|
{
|
||||||
"destination": "/etc/loki/loki-local-config.yaml",
|
"destination": "/etc/loki/loki-local-config.yaml",
|
||||||
|
@ -28,6 +23,29 @@
|
||||||
"group": "grafana"
|
"group": "grafana"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"Repositories": {
|
||||||
|
"Grafana": {
|
||||||
|
"type": "helm",
|
||||||
|
"name": "grafana",
|
||||||
|
"url": "https://grafana.github.io/helm-charts",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Packages": {
|
||||||
|
"loki": {
|
||||||
|
"name": "loki",
|
||||||
|
"action": "install"
|
||||||
|
},
|
||||||
|
"promtail": {
|
||||||
|
"name": "loki-promtail",
|
||||||
|
"action": "install"
|
||||||
|
},
|
||||||
|
"loki-helm": {
|
||||||
|
"type": "helm",
|
||||||
|
"name": "loki",
|
||||||
|
"repo": "grafana/loki-simple-scalable"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Vars": {
|
"Vars": {
|
||||||
"AuthEnabled": false,
|
"AuthEnabled": false,
|
||||||
"User": "loki",
|
"User": "loki",
|
||||||
|
@ -60,7 +78,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Grafana": {
|
"Grafana": {
|
||||||
"EnabledBy": { "var": "EnableGrafana", "value": true },
|
|
||||||
"ConfigFiles": [
|
"ConfigFiles": [
|
||||||
{
|
{
|
||||||
"destination": "/etc/grafana.ini",
|
"destination": "/etc/grafana.ini",
|
||||||
|
@ -70,6 +87,12 @@
|
||||||
"group": "grafana"
|
"group": "grafana"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"Packages": {
|
||||||
|
"grafana": {
|
||||||
|
"name": "grafana",
|
||||||
|
"action": "install"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Vars": {
|
"Vars": {
|
||||||
"AuthEnabled": false,
|
"AuthEnabled": false,
|
||||||
"User": "toto",
|
"User": "toto",
|
||||||
|
@ -83,9 +106,12 @@
|
||||||
"shell": "/bin/nologin"
|
"shell": "/bin/nologin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Daemon": {
|
"Daemons": {
|
||||||
"name": "grafana",
|
"grafana": {
|
||||||
"enabled": true
|
"name": "grafana",
|
||||||
|
"type": "auto",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,6 @@ import (
|
||||||
|
|
||||||
var CacheFilePath = "/var/cache/templater.db"
|
var CacheFilePath = "/var/cache/templater.db"
|
||||||
|
|
||||||
type SimpleCondition struct {
|
|
||||||
Var string `json:"var"`
|
|
||||||
Value bool `json:"value"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TemplaterConfig struct {
|
type TemplaterConfig struct {
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
TemplateDirectory string `json:"TemplateDirectory"`
|
TemplateDirectory string `json:"TemplateDirectory"`
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package templater
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"forge.cadoles.com/pcaseiro/templatefile/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SystemPackage struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
OS string `json:"os"`
|
||||||
|
Distribution string `json:"distribution"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *SystemPackage) SetDistribution() error {
|
||||||
|
OSConfig, err := utils.ReadOSRelease()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Distribution = OSConfig["ID_LIKE"]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (p *SystemPackage) SetOS() error {
|
||||||
|
p.OS = runtime.GOOS
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *SystemPackage) Manage() error {
|
||||||
|
var pkErr error
|
||||||
|
var stdErr []byte
|
||||||
|
|
||||||
|
if p.OS == "" {
|
||||||
|
if err := p.SetOS(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Distribution == "" {
|
||||||
|
if err := p.SetDistribution(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Processing %s package\n", p.Name)
|
||||||
|
switch os := p.Distribution; os {
|
||||||
|
case "debian", "ubuntu":
|
||||||
|
_, stdErr, pkErr = utils.RunSystemCommand("apt", "install", "-y", p.Name)
|
||||||
|
case "alpine":
|
||||||
|
_, stdErr, pkErr = utils.RunSystemCommand("apk", "add", p.Name)
|
||||||
|
case "redhat":
|
||||||
|
_, stdErr, pkErr = utils.RunSystemCommand("yum", "install", "-y", p.Name)
|
||||||
|
case "arch":
|
||||||
|
_, stdErr, pkErr = utils.RunSystemCommand("pacman", "-Suy", p.Name)
|
||||||
|
default:
|
||||||
|
pkErr = fmt.Errorf("Unsupported OS %s [%s]", p.OS, stdErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkErr != nil {
|
||||||
|
var msg string
|
||||||
|
if len(stdErr) != 0 {
|
||||||
|
msg = string(stdErr)
|
||||||
|
} else {
|
||||||
|
msg = pkErr.Error()
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Package %s, os %s, failed with error: %v", p.Name, p.OS, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package templater
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"forge.cadoles.com/pcaseiro/templatefile/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type APKRepository struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *APKRepository) Add() error {
|
||||||
|
data := fmt.Sprintf("%s", hr.URL)
|
||||||
|
file, err := os.OpenFile("/etc/apk/repositories", os.O_APPEND|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
if _, err := file.WriteString(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *APKRepository) Update() error {
|
||||||
|
if _, stdErr, err := utils.RunSystemCommand("apk", "update"); err != nil {
|
||||||
|
return fmt.Errorf("%s [%s]", stdErr, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *APKRepository) Delete() error {
|
||||||
|
fileBytes, err := ioutil.ReadFile("/etc/apk/repositories")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(fileBytes), "\n")
|
||||||
|
for i, line := range lines {
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (hr *APKRepository) Manage() error {
|
||||||
|
if hr.Enabled {
|
||||||
|
return hr.Add()
|
||||||
|
} else {
|
||||||
|
return hr.Delete()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package templater
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"forge.cadoles.com/pcaseiro/templatefile/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DebRepository struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *DebRepository) Add() error {
|
||||||
|
//deb http://fr.archive.ubuntu.com/ubuntu/ focal main restricted
|
||||||
|
|
||||||
|
data := fmt.Sprintf("deb %s", hr.URL)
|
||||||
|
if err := os.WriteFile("/etc/apt/source.list.d", []byte(data)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *DebRepository) Update() error {
|
||||||
|
if _, stdErr, err := utils.RunSystemCommand("apt", "update", "-y"); err != nil {
|
||||||
|
return fmt.Errorf("%s [%s]", stdErr, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *DebRepository) Delete() error {
|
||||||
|
//TODO
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (hr *DebRepository) Manage() error {
|
||||||
|
if hr.Enabled {
|
||||||
|
return hr.Add()
|
||||||
|
} else {
|
||||||
|
return hr.Delete()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package templater
|
||||||
|
|
||||||
|
type HelmRepository struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *HelmRepository) Add() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *HelmRepository) Update() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hr *HelmRepository) Delete() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (hr *HelmRepository) Manage() error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package templater
|
||||||
|
|
||||||
|
type PackageRepository interface { // création de L'interface Forme
|
||||||
|
Manage() error // signature de la méthode Perimetre()
|
||||||
|
Update() error
|
||||||
|
Add() error
|
||||||
|
Delete() error
|
||||||
|
}
|
|
@ -7,22 +7,32 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
EnabledBy SimpleCondition `json:"EnabledBy"`
|
ConfigFiles []ConfigFile `json:"ConfigFiles"`
|
||||||
ConfigFiles []ConfigFile `json:"ConfigFiles"`
|
Vars map[string]interface{} `json:"Vars"`
|
||||||
Vars map[string]interface{} `json:"Vars"`
|
Daemons map[string]SystemService `json:"Daemons"`
|
||||||
Daemon SystemService `json:"Daemon"`
|
Users map[string]SystemUser `json:"Users"`
|
||||||
Users map[string]SystemUser `json:"Users"`
|
Packages map[string]SystemPackage `json:"Packages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Manage(templateDir string) error {
|
func (s *Service) Manage(templateDir string) error {
|
||||||
|
// Manage system packages
|
||||||
|
for _, pack := range s.Packages {
|
||||||
|
err := pack.Manage()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err := processConfigFiles(s.ConfigFiles, s.Vars, templateDir)
|
err := processConfigFiles(s.ConfigFiles, s.Vars, templateDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ProcessingTemplatesFailed with error: %v", err)
|
return fmt.Errorf("ProcessingTemplatesFailed with error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Daemon.Manage()
|
for _, daemon := range s.Daemons {
|
||||||
if err != nil {
|
err = daemon.Manage()
|
||||||
return fmt.Errorf("Error managing service daemons: %v", err)
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error managing service daemons: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ type SystemService struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
ToStart bool `json:"start"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sys *SystemService) SetType() {
|
func (sys *SystemService) SetType() {
|
||||||
|
@ -34,8 +35,16 @@ func (sys *SystemService) SetType() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sys *SystemService) Action() error {
|
||||||
|
if sys.ToStart {
|
||||||
|
return sys.Start()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (sys *SystemService) Manage() error {
|
func (sys *SystemService) Manage() error {
|
||||||
if sys.Type == "" {
|
// By default if the property sys.ToStart is empty
|
||||||
|
if sys.Type == "" || sys.Type == "auto" {
|
||||||
sys.SetType()
|
sys.SetType()
|
||||||
}
|
}
|
||||||
if sys.Enabled {
|
if sys.Enabled {
|
||||||
|
@ -43,6 +52,10 @@ func (sys *SystemService) Manage() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err = sys.Action(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Nothing to do for daemon %s\n", sys.Name)
|
fmt.Printf("Nothing to do for daemon %s\n", sys.Name)
|
||||||
}
|
}
|
||||||
|
@ -50,12 +63,38 @@ func (sys *SystemService) Manage() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sys *SystemService) Start() error {
|
func (sys *SystemService) Start() error {
|
||||||
fmt.Printf("Starting %s\n", sys.Name)
|
fmt.Printf("Starting system service : %s\n", sys.Name)
|
||||||
|
if sys.Type == "systemd" {
|
||||||
|
_, stdErr, err := utils.RunSystemCommand("systemctl", "start", sys.Name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("System service %s \n * Start error:\n - %s", sys.Name, stdErr)
|
||||||
|
}
|
||||||
|
} else if sys.Type == "openrc" {
|
||||||
|
_, stdErr, err := utils.RunSystemCommand("service", sys.Name, "stop")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("System service %s \n * Enable error:\n - %s", sys.Name, stdErr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Unsupported service type %s for service %s", sys.Type, sys.Name)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sys *SystemService) Stop() error {
|
func (sys *SystemService) Stop() error {
|
||||||
fmt.Printf("Stoping %s\n", sys.Name)
|
fmt.Printf("Stoping system service : %s\n", sys.Name)
|
||||||
|
if sys.Type == "systemd" {
|
||||||
|
_, stdErr, err := utils.RunSystemCommand("systemctl", "stop", sys.Name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("System service %s \n * Stop error:\n - %s", sys.Name, stdErr)
|
||||||
|
}
|
||||||
|
} else if sys.Type == "openrc" {
|
||||||
|
_, stdErr, err := utils.RunSystemCommand("service", sys.Name, "stop")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("System service %s \n * Enable error:\n - %s", sys.Name, stdErr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Unsupported service type %s for service %s", sys.Type, sys.Name)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +105,10 @@ func (sys *SystemService) Enable() error {
|
||||||
return fmt.Errorf("System service %s \n * Enable error:\n - %s", sys.Name, stdErr)
|
return fmt.Errorf("System service %s \n * Enable error:\n - %s", sys.Name, stdErr)
|
||||||
}
|
}
|
||||||
} else if sys.Type == "openrc" {
|
} else if sys.Type == "openrc" {
|
||||||
return nil
|
_, stdErr, err := utils.RunSystemCommand("rc-update", "add", sys.Name, "default")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("System service %s \n * Enable error:\n - %s", sys.Name, stdErr)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Unsupported service type %s for service %s", sys.Type, sys.Name)
|
return fmt.Errorf("Unsupported service type %s for service %s", sys.Type, sys.Name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
ini "gopkg.in/ini.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var osReleaseFile = "/etc/os-release"
|
||||||
|
|
||||||
|
func ReadOSRelease() (map[string]string, error) {
|
||||||
|
cfg, err := ini.Load(osReleaseFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Fail to read file: %v ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigParams := make(map[string]string)
|
||||||
|
ConfigParams["ID"] = cfg.Section("").Key("ID").String()
|
||||||
|
idLike := cfg.Section("").Key("ID_LIKE").String()
|
||||||
|
if idLike != "" {
|
||||||
|
ConfigParams["ID_LIKE"] = idLike
|
||||||
|
} else {
|
||||||
|
ConfigParams["ID_LIKE"] = ConfigParams["ID"]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConfigParams, nil
|
||||||
|
}
|
Loading…
Reference in New Issue