feat(api): adding api server code
templater can be used as a commmand line tool or as an api server.
This commit is contained in:
parent
b22cbcaf78
commit
0f7174ed6f
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@ LINT_ARGS ?= ./...
|
||||||
DESTDIR ?= "/usr/local"
|
DESTDIR ?= "/usr/local"
|
||||||
|
|
||||||
bin:
|
bin:
|
||||||
GOOS=linux go build -o bin/templater-linux main.go
|
GOOS=linux go build -o bin/templater-linux cmd/templater.go
|
||||||
upx bin/templater-linux
|
upx bin/templater-linux
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
package api
|
|
@ -0,0 +1,23 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"forge.cadoles.com/pcaseiro/templatefile/pkg/templater"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// The template to process
|
||||||
|
templateType := os.Args[1]
|
||||||
|
templateFile := os.Args[2]
|
||||||
|
config := []byte(os.Args[3])
|
||||||
|
|
||||||
|
if templateType == "go" {
|
||||||
|
fmt.Printf("%s", templater.ProcessGoTemplate(templateFile, config))
|
||||||
|
} else if templateType == "hcl" {
|
||||||
|
fmt.Printf("%s", templater.ProcessHCLTemplate(templateFile, config))
|
||||||
|
} else {
|
||||||
|
panic(fmt.Errorf("Unsupported template type"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"Name": "loki",
|
||||||
|
"ConfigFiles": [
|
||||||
|
{
|
||||||
|
"destination": "/etc/loki/loki-local-config.yaml",
|
||||||
|
"source": "loki-local-config.pktpl.hcl",
|
||||||
|
"mod": "600"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"AuthEnabled": false,
|
||||||
|
"User": "loki",
|
||||||
|
"Group": "grafana",
|
||||||
|
"HTTPPort": "3100",
|
||||||
|
"GRPCPort": "9096",
|
||||||
|
"AlertManagerURL": "http://localhost:9093",
|
||||||
|
"StorageRoot": "/var/loki",
|
||||||
|
"SharedStore": "filesystem",
|
||||||
|
"ObjectStore": "filesystem",
|
||||||
|
"LogLevel": "error",
|
||||||
|
"S3": {
|
||||||
|
"URL": "",
|
||||||
|
"BucketName": "",
|
||||||
|
"APIKey": "",
|
||||||
|
"APISecretKey": ""
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
%{ if AuthEnabled ~}
|
||||||
|
auth_enabled: true
|
||||||
|
%{ else }
|
||||||
|
auth_enabled: false
|
||||||
|
%{ endif }
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: ${HTTPPort}
|
||||||
|
grpc_listen_port: ${GRPCPort}
|
||||||
|
log_level: ${LogLevel}
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
wal:
|
||||||
|
enabled: true
|
||||||
|
dir: ${StorageRoot}/wal
|
||||||
|
flush_on_shutdown: true
|
||||||
|
lifecycler:
|
||||||
|
address: 127.0.0.1
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
replication_factor: 1
|
||||||
|
final_sleep: 0s
|
||||||
|
chunk_idle_period: 1h # Any chunk not receiving new logs in this time will be flushed
|
||||||
|
max_chunk_age: 1h # All chunks will be flushed when they hit this age, default is 1h
|
||||||
|
chunk_target_size: 1048576 # Loki will attempt to build chunks up to 1.5MB, flushing first if chunk_idle_period or max_chunk_age is reached first
|
||||||
|
chunk_retain_period: 30s # Must be greater than index read cache TTL if using an index cache (Default index read cache TTL is 5m)
|
||||||
|
max_transfer_retries: 0 # Chunk transfers disabled
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2020-05-15
|
||||||
|
store: boltdb-shipper
|
||||||
|
object_store: ${ObjectStore}
|
||||||
|
schema: v11
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
boltdb_shipper:
|
||||||
|
active_index_directory: ${StorageRoot}/index
|
||||||
|
shared_store: ${SharedStore}
|
||||||
|
cache_location: ${StorageRoot}/cache
|
||||||
|
cache_ttl: 168h
|
||||||
|
|
||||||
|
%{ if ObjectStore == "filesystem" ~}
|
||||||
|
filesystem:
|
||||||
|
directory: ${StorageRoot}/chunks
|
||||||
|
%{ else }
|
||||||
|
aws:
|
||||||
|
s3: s3://${S3.APIKey}:${S3.APISecretKey}@${S3.URL}/${S3.BucketName}
|
||||||
|
s3forcepathstyle: true
|
||||||
|
%{ endif }
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
shared_store: ${SharedStore}
|
||||||
|
working_directory: ${StorageRoot}/compactor
|
||||||
|
compaction_interval: 10m
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
|
||||||
|
chunk_store_config:
|
||||||
|
max_look_back_period: 0s
|
||||||
|
|
||||||
|
table_manager:
|
||||||
|
retention_deletes_enabled: false
|
||||||
|
retention_period: 0s
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: ${StorageRoot}/rules
|
||||||
|
rule_path: ${StorageRoot}/rules
|
||||||
|
alertmanager_url: ${AlertManagerURL}
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
enable_api: true
|
|
@ -0,0 +1,82 @@
|
||||||
|
{{ if .AuthEnabled }}
|
||||||
|
auth_enabled: true
|
||||||
|
{{ else }}
|
||||||
|
auth_enabled: false
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: {{ .HTTPPort }}
|
||||||
|
grpc_listen_port: {{ .GRPCPort }}
|
||||||
|
log_level: {{ .LogLevel }}
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
wal:
|
||||||
|
enabled: true
|
||||||
|
dir: {{ .StorageRoot }}/wal
|
||||||
|
flush_on_shutdown: true
|
||||||
|
lifecycler:
|
||||||
|
address: 127.0.0.1
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
replication_factor: 1
|
||||||
|
final_sleep: 0s
|
||||||
|
chunk_idle_period: 1h # Any chunk not receiving new logs in this time will be flushed
|
||||||
|
max_chunk_age: 1h # All chunks will be flushed when they hit this age, default is 1h
|
||||||
|
chunk_target_size: 1048576 # Loki will attempt to build chunks up to 1.5MB, flushing first if chunk_idle_period or max_chunk_age is reached first
|
||||||
|
chunk_retain_period: 30s # Must be greater than index read cache TTL if using an index cache (Default index read cache TTL is 5m)
|
||||||
|
max_transfer_retries: 0 # Chunk transfers disabled
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2020-05-15
|
||||||
|
store: boltdb-shipper
|
||||||
|
object_store: {{ .ObjectStore }}
|
||||||
|
schema: v11
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
boltdb_shipper:
|
||||||
|
active_index_directory: {{ .StorageRoot }}/index
|
||||||
|
shared_store: {{ .SharedStore }}
|
||||||
|
cache_location: {{ .StorageRoot }}/cache
|
||||||
|
cache_ttl: 168h
|
||||||
|
|
||||||
|
{{ if eq (.ObjectStore) ("filesystem") }}
|
||||||
|
filesystem:
|
||||||
|
directory: {{ .StorageRoot }}/chunks
|
||||||
|
{{ else }}
|
||||||
|
aws:
|
||||||
|
s3: s3://{{ .S3.APIKey }}:{{ .S3.APISecretKey}}@{{ .S3.URL}}/{{ .S3.BucketName}}
|
||||||
|
s3forcepathstyle: true
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
shared_store: {{ .SharedStore }}
|
||||||
|
working_directory: {{ .StorageRoot }}/compactor
|
||||||
|
compaction_interval: 10m
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
|
||||||
|
chunk_store_config:
|
||||||
|
max_look_back_period: 0s
|
||||||
|
|
||||||
|
table_manager:
|
||||||
|
retention_deletes_enabled: false
|
||||||
|
retention_period: 0s
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: {{ .StorageRoot }}/rules
|
||||||
|
rule_path: {{ .StorageRoot }}/rules
|
||||||
|
alertmanager_url: {{ .AlertManagerURL }}
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
enable_api: true
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package templater
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
encjson "encoding/json"
|
encjson "encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
@ -10,45 +11,38 @@ import (
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
ctyjson "github.com/zclconf/go-cty/cty/json"
|
ctyjson "github.com/zclconf/go-cty/cty/json"
|
||||||
|
|
||||||
|
"forge.cadoles.com/pcaseiro/templatefile/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkErr(e error) {
|
func ProcessGoTemplate(file string, config []byte) string {
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkDiags(diag hcl.Diagnostics) {
|
|
||||||
if diag.HasErrors() {
|
|
||||||
panic(diag.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func processGoTemplate(file string, config []byte) {
|
|
||||||
|
|
||||||
// The JSON configuration
|
// The JSON configuration
|
||||||
var confData map[string]interface{}
|
var confData map[string]interface{}
|
||||||
|
var res bytes.Buffer
|
||||||
|
|
||||||
err := encjson.Unmarshal(config, &confData)
|
err := encjson.Unmarshal(config, &confData)
|
||||||
checkErr(err)
|
utils.CheckErr(err)
|
||||||
|
|
||||||
// Read the template
|
// Read the template
|
||||||
data, err := os.ReadFile(file)
|
data, err := os.ReadFile(file)
|
||||||
checkErr(err)
|
utils.CheckErr(err)
|
||||||
|
|
||||||
tpl, err := template.New("conf").Parse(string(data))
|
tpl, err := template.New("conf").Parse(string(data))
|
||||||
checkErr(err)
|
utils.CheckErr(err)
|
||||||
|
|
||||||
checkErr(tpl.Execute(os.Stdout, confData))
|
utils.CheckErr(tpl.Execute(&res, confData))
|
||||||
|
|
||||||
|
return res.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func processHCLTemplate(file string, config []byte) {
|
func ProcessHCLTemplate(file string, config []byte) string {
|
||||||
|
|
||||||
fct, err := os.ReadFile(file)
|
fct, err := os.ReadFile(file)
|
||||||
checkErr(err)
|
utils.CheckErr(err)
|
||||||
|
|
||||||
expr, diags := hclsyntax.ParseTemplate(fct, file, hcl.Pos{Line: 1, Column: 1})
|
expr, diags := hclsyntax.ParseTemplate(fct, file, hcl.Pos{Line: 0, Column: 1})
|
||||||
checkDiags(diags)
|
utils.CheckDiags(diags)
|
||||||
|
|
||||||
// Retrieve values from JSON
|
// Retrieve values from JSON
|
||||||
var varsVal cty.Value
|
var varsVal cty.Value
|
||||||
|
@ -56,7 +50,7 @@ func processHCLTemplate(file string, config []byte) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
/* Maybe one day
|
/* Maybe one day
|
||||||
cexpr, diags := hclsyntax.ParseExpression(config, "", hcl.Pos{Line: 1, Column: 1})
|
cexpr, diags := hclsyntax.ParseExpression(config, "", hcl.Pos{Line: 0, Column: 1})
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
panic(diags.Error())
|
panic(diags.Error())
|
||||||
}
|
}
|
||||||
|
@ -66,7 +60,7 @@ func processHCLTemplate(file string, config []byte) {
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
varsVal, err = ctyjson.Unmarshal(config, ctyType)
|
varsVal, err = ctyjson.Unmarshal(config, ctyType)
|
||||||
checkErr(err)
|
utils.CheckErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := &hcl.EvalContext{
|
ctx := &hcl.EvalContext{
|
||||||
|
@ -91,20 +85,5 @@ func processHCLTemplate(file string, config []byte) {
|
||||||
panic(diags.Error())
|
panic(diags.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s", val.AsString())
|
return val.AsString()
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// The template to process
|
|
||||||
templateType := os.Args[1]
|
|
||||||
templateFile := os.Args[2]
|
|
||||||
config := []byte(os.Args[3])
|
|
||||||
|
|
||||||
if templateType == "go" {
|
|
||||||
processGoTemplate(templateFile, config)
|
|
||||||
} else if templateType == "hcl" {
|
|
||||||
processHCLTemplate(templateFile, config)
|
|
||||||
} else {
|
|
||||||
panic(fmt.Errorf("Unsupported template type"))
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckErr(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckDiags(diag hcl.Diagnostics) {
|
||||||
|
if diag.HasErrors() {
|
||||||
|
panic(diag.Error())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue