Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c12bd6dfa | ||
|
|
b26eec0a18 | ||
|
|
5f5849e557 | ||
|
|
8ba09cc6f2 |
@@ -1 +1,21 @@
|
||||
# Foundry
|
||||
|
||||
## Schema
|
||||
Definition:
|
||||
|
||||
### Platforms
|
||||
- docker
|
||||
- linux
|
||||
- kubernetes
|
||||
- aws
|
||||
- gcp
|
||||
- azure
|
||||
- windows
|
||||
- aws_marketplace
|
||||
|
||||
# Installation
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
schemaVersion: v1
|
||||
platform: linux
|
||||
components:
|
||||
signoz:
|
||||
enabled: true
|
||||
replicas: 3 # HA configuration
|
||||
version: "0.39.2"
|
||||
env:
|
||||
- key: CLICKHOUSE_HOST
|
||||
value: localhost:9000
|
||||
clickhouse:
|
||||
enabled: true
|
||||
replicas: 3 # HA configuration
|
||||
version: "24.8"
|
||||
zookeeper:
|
||||
enabled: true
|
||||
replicas: 1 # Single instance
|
||||
version: "3.7"
|
||||
signoz-collector:
|
||||
enabled: true
|
||||
replicas: 2 # HA configuration
|
||||
version: "0.39.2"
|
||||
+98
-1
@@ -1,19 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/errors"
|
||||
"cuelang.org/go/encoding/json"
|
||||
"cuelang.org/go/encoding/yaml"
|
||||
"github.com/SigNoz/foundry/internal/instrumentation"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
errorFilenotFound = errors.New("File not found")
|
||||
errorSchemaNotFound = errors.New("Schema file not found")
|
||||
logger = instrumentation.NewLogger(cfg.Debug).With(slog.String("cmd.name", "gauge"))
|
||||
)
|
||||
|
||||
const (
|
||||
schemaFileName = "../../internal/schema/schema.cue"
|
||||
)
|
||||
|
||||
func registerGaugeCmd(rootCmd *cobra.Command) {
|
||||
gaugeCmd := &cobra.Command{
|
||||
Use: "gauge",
|
||||
Short: "Gauge whether required tools are available.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
logger := instrumentation.NewLogger(cfg.Debug).With(slog.String("cmd.name", "gauge"))
|
||||
ctx := cmd.Context()
|
||||
filePath := cfg.File
|
||||
err := validateConfig(filePath)
|
||||
if err != nil {
|
||||
logger.ErrorContext(ctx, "failed to validate config", slog.String("cfg.file", cfg.File), slog.String("error", err.Error()))
|
||||
}
|
||||
|
||||
logger.DebugContext(ctx, "starting command", slog.String("cfg.file", cfg.File))
|
||||
return nil
|
||||
@@ -22,3 +44,78 @@ func registerGaugeCmd(rootCmd *cobra.Command) {
|
||||
|
||||
rootCmd.AddCommand(gaugeCmd)
|
||||
}
|
||||
|
||||
func compileDataFile(ctx *cue.Context, filename string, data []byte) (cue.Value, error) {
|
||||
ext := filepath.Ext(filename)
|
||||
|
||||
var expr cue.Value
|
||||
var err error
|
||||
|
||||
switch ext {
|
||||
case ".yaml", ".yml":
|
||||
yamlExpr, err := yaml.Extract(filename, data)
|
||||
if err != nil {
|
||||
return cue.Value{}, fmt.Errorf("failed to parse YAML: %w", err)
|
||||
}
|
||||
expr = ctx.BuildFile(yamlExpr)
|
||||
|
||||
case ".json":
|
||||
jsonExpr, err := json.Extract(filename, data)
|
||||
if err != nil {
|
||||
return cue.Value{}, fmt.Errorf("failed to parse JSON: %w", err)
|
||||
}
|
||||
expr = ctx.BuildExpr(jsonExpr)
|
||||
|
||||
default:
|
||||
return cue.Value{}, fmt.Errorf("unsupported file format: %s (supported: .yaml, .yml, .json, .toml)", ext)
|
||||
}
|
||||
|
||||
if expr.Err() != nil {
|
||||
return cue.Value{}, fmt.Errorf("config parsing error:\n%s", errors.Details(expr.Err(), nil))
|
||||
}
|
||||
|
||||
return expr, err
|
||||
}
|
||||
|
||||
func validateConfig(filename string) error {
|
||||
configFile, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return errorFilenotFound
|
||||
}
|
||||
|
||||
schemaFile, err := os.ReadFile(schemaFileName)
|
||||
if err != nil {
|
||||
return errorSchemaNotFound
|
||||
}
|
||||
|
||||
ctx := cuecontext.New()
|
||||
|
||||
// Compile schema
|
||||
schema := ctx.CompileBytes(schemaFile, cue.Filename(schemaFileName))
|
||||
if schema.Err() != nil {
|
||||
return fmt.Errorf("schema compilation error:\n%s", errors.Details(schema.Err(), nil))
|
||||
}
|
||||
|
||||
// Compile data based on file extension
|
||||
data, err := compileDataFile(ctx, filename, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Lookup #Config definition
|
||||
configSchema := schema.LookupPath(cue.ParsePath("#Config"))
|
||||
if configSchema.Err() != nil {
|
||||
return fmt.Errorf("#Config not found in schema:\n%s", errors.Details(configSchema.Err(), nil))
|
||||
}
|
||||
|
||||
// Unify and validate
|
||||
unified := configSchema.Unify(data)
|
||||
if err := unified.Validate(cue.Concrete(true)); err != nil {
|
||||
// Use errors.Details for much better error messages
|
||||
logger.Error("Validation failed")
|
||||
return fmt.Errorf("validation failed")
|
||||
}
|
||||
|
||||
logger.Info("✓ Valid Schema")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,9 +2,22 @@ module github.com/SigNoz/foundry
|
||||
|
||||
go 1.25.3
|
||||
|
||||
require github.com/spf13/cobra v1.10.1
|
||||
require (
|
||||
cuelang.org/go v0.15.1
|
||||
github.com/spf13/cobra v1.10.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
|
||||
github.com/emicklei/proto v1.14.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.9 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/net v0.46.0 // indirect
|
||||
golang.org/x/text v0.30.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,10 +1,63 @@
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 h1:4k1yAtPvZJZQTu8DRY8muBo0LHv6TqtrE0AO5n6IPYs=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084/go.mod h1:4WWeZNxUO1vRoZWAHIG0KZOd6dA25ypyWuwD3ti0Tdc=
|
||||
cuelang.org/go v0.15.1 h1:MRnjc/KJE+K42rnJ3a+425f1jqXeOOgq9SK4tYRTtWw=
|
||||
cuelang.org/go v0.15.1/go.mod h1:NYw6n4akZcTjA7QQwJ1/gqWrrhsN4aZwhcAL0jv9rZE=
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
|
||||
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I=
|
||||
github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 h1:s1LvMaU6mVwoFtbxv/rCZKE7/fwDmDY684FfUe4c1Io=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
|
||||
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package schema
|
||||
|
||||
// Schema version must follow semantic versioning
|
||||
#SchemaVersion: =~"^v[0-9]+$"
|
||||
|
||||
// Platform enumeration - add more platforms as needed
|
||||
#Platform: "docker" | "linux" | "kubernetes" | "aws" | "gcp" | "azure" | "windows"
|
||||
|
||||
// Environment variable key-value pair
|
||||
#EnvVar: {
|
||||
key: string
|
||||
value: string
|
||||
}
|
||||
|
||||
// Component definition
|
||||
#Component: {
|
||||
enabled: bool
|
||||
replicas: int & >=1
|
||||
version: string & =~"^[0-9]+\\.[0-9]+(\\.[0-9]+)?(-.*)?$"
|
||||
env?: [...#EnvVar]
|
||||
}
|
||||
|
||||
// Platform-specific requirements
|
||||
_requirements: {
|
||||
docker: ["docker", "docker-compose"]
|
||||
linux: ["systemd", "curl", "tar"]
|
||||
kubernetes: ["kubectl", "helm"]
|
||||
aws: ["aws-cli", "kubectl", "helm"]
|
||||
gcp: ["gcloud", "kubectl", "helm"]
|
||||
azure: ["az-cli", "kubectl", "helm"]
|
||||
windows: ["powershell", "chocolatey"]
|
||||
}
|
||||
|
||||
// Main configuration schema
|
||||
#Config: {
|
||||
schemaVersion: #SchemaVersion
|
||||
platform: #Platform
|
||||
|
||||
// Components involved in the deployment
|
||||
components: [string]: #Component
|
||||
|
||||
// Requirements based on platform
|
||||
requirements: _requirements[platform]
|
||||
}
|
||||
|
||||
// Validate that the config conforms to the schema
|
||||
#Config
|
||||
Reference in New Issue
Block a user