github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/tanka/static.go (about) 1 package tanka 2 3 import ( 4 "encoding/json" 5 6 "github.com/grafana/tanka/pkg/jsonnet/implementations/types" 7 "github.com/grafana/tanka/pkg/spec" 8 "github.com/grafana/tanka/pkg/spec/v1alpha1" 9 "github.com/rs/zerolog/log" 10 ) 11 12 // StaticLoader loads an environment from a static file called `spec.json`. 13 // Jsonnet is evaluated as normal 14 type StaticLoader struct { 15 jsonnetImpl types.JsonnetImplementation 16 } 17 18 func (s StaticLoader) Load(path string, opts LoaderOpts) (*v1alpha1.Environment, error) { 19 config, err := s.Peek(path, opts) 20 if err != nil { 21 return nil, err 22 } 23 24 data, err := s.Eval(path, opts) 25 if err != nil { 26 return nil, err 27 } 28 config.Data = data 29 30 return config, nil 31 } 32 33 func (s StaticLoader) Peek(path string, _ LoaderOpts) (*v1alpha1.Environment, error) { 34 config, err := parseStaticSpec(path) 35 if err != nil { 36 return nil, err 37 } 38 39 return config, nil 40 } 41 42 func (s StaticLoader) List(path string, opts LoaderOpts) ([]*v1alpha1.Environment, error) { 43 env, err := s.Peek(path, opts) 44 if err != nil { 45 return nil, err 46 } 47 48 return []*v1alpha1.Environment{env}, nil 49 } 50 51 func (s *StaticLoader) Eval(path string, opts LoaderOpts) (interface{}, error) { 52 config, err := s.Peek(path, opts) 53 if err != nil { 54 return nil, err 55 } 56 57 envCode, err := specToExtCode(config) 58 if err != nil { 59 return nil, err 60 } 61 opts.ExtCode.Set(environmentExtCode, envCode) 62 63 raw, err := evalJsonnet(path, s.jsonnetImpl, opts.JsonnetOpts) 64 if err != nil { 65 return nil, err 66 } 67 68 var data interface{} 69 if err := json.Unmarshal([]byte(raw), &data); err != nil { 70 return nil, err 71 } 72 73 return data, nil 74 } 75 76 func specToExtCode(spec *v1alpha1.Environment) (string, error) { 77 spec.Data = nil 78 data, err := json.Marshal(spec) 79 if err != nil { 80 return "", err 81 } 82 83 return string(data), nil 84 } 85 86 // parseStaticSpec parses the `spec.json` of the environment and returns a 87 // *kubernetes.Kubernetes from it 88 func parseStaticSpec(path string) (*v1alpha1.Environment, error) { 89 env, err := spec.ParseDir(path) 90 if err != nil { 91 switch err.(type) { 92 // the config includes deprecated fields 93 case spec.ErrDeprecated: 94 log.Warn().Err(err).Msg("encountered deprecated fields in spec.json") 95 // spec.json missing. we can still work with the default value 96 case spec.ErrNoSpec: 97 return env, nil 98 // some other error 99 default: 100 return nil, err 101 } 102 } 103 104 return env, nil 105 }