Skip to content

Commit

Permalink
feat(api): Peek (grafana#467)
Browse files Browse the repository at this point in the history
* feat(api): Peek

Introduces a new functionality called Peek with behaves like Load, but
only loads metadata.

Because this is much faster than full loading, this can be used at
places where only metadata is required.

This formalizes behavior that was previously possible by passing
`EnvsOnlyEvalScript`. The benefit of having this as an interface
implementation is that it can make better use of underlying details,
such as that the static loader does need to start a costly Jsonnet VM
for only parsing `spec.json`

* refactor(api): use Peek

Applies the Peek function at places where it makes sense

* style(api): baseDir in detectLoader

* feat(api): export DetectLoader
  • Loading branch information
sh0rez authored Jan 8, 2021
1 parent 3b592ee commit e5b5266
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 30 deletions.
18 changes: 5 additions & 13 deletions cmd/tk/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"text/tabwriter"
Expand Down Expand Up @@ -78,7 +77,11 @@ func envSetCmd() *cli.Command {
tmp.Spec.APIServer = server
}

cfg := setupConfiguration(path)
cfg, err := tanka.Peek(path, tanka.JsonnetOpts{})
if err != nil {
return err
}

if tmp.Spec.APIServer != "" && tmp.Spec.APIServer != cfg.Spec.APIServer {
fmt.Printf("updated spec.apiServer (`%s -> `%s`)\n", cfg.Spec.APIServer, tmp.Spec.APIServer)
cfg.Spec.APIServer = tmp.Spec.APIServer
Expand Down Expand Up @@ -276,14 +279,3 @@ func envListCmd() *cli.Command {
}
return cmd
}

func setupConfiguration(baseDir string) *v1alpha1.Environment {
env, err := tanka.Load(baseDir, tanka.Opts{
JsonnetOpts: tanka.JsonnetOpts{EvalScript: tanka.EnvsOnlyEvalScript},
})
if err != nil {
log.Fatalln(err)
}

return env.Env
}
6 changes: 2 additions & 4 deletions cmd/tk/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,10 @@ func exportCmd() *cli.Command {
}

// validate environment
jsonnetOpts := opts.ParseParallelOpts.JsonnetOpts
jsonnetOpts.EvalScript = tanka.EnvsOnlyEvalScript
_, err := tanka.Load(path, tanka.Opts{JsonnetOpts: jsonnetOpts})
if err != nil {
if _, err := tanka.Peek(path, opts.ParseParallelOpts.JsonnetOpts); err != nil {
return err
}

paths = append(paths, path)
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/tanka/inline.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (i *InlineLoader) Load(path string, opts JsonnetOpts) (*v1alpha1.Environmen
return env, nil
}

func (i *InlineLoader) Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
opts.EvalScript = EnvsOnlyEvalScript
return i.Load(path, opts)
}

// extractEnvs filters out any Environment manifests
func extractEnvs(data interface{}) (manifest.List, error) {
// Scan for everything that looks like a Kubernetes object
Expand Down
33 changes: 24 additions & 9 deletions pkg/tanka/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ import (
// Load loads the Environment at `path`. It automatically detects whether to
// load inline or statically
func Load(path string, opts Opts) (*LoadResult, error) {
_, base, err := jpath.Dirs(path)
if err != nil {
return nil, err
}

loader, err := detectLoader(base)
loader, err := DetectLoader(path)
if err != nil {
return nil, err
}
Expand All @@ -44,11 +39,27 @@ func Load(path string, opts Opts) (*LoadResult, error) {
return &LoadResult{Env: env, Resources: processed}, nil
}

// detectLoader detects whether the environment is inline or static and picks
// Peek loads the metadata of the environment at path. To get resources as well,
// use Load
func Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
loader, err := DetectLoader(path)
if err != nil {
return nil, err
}

return loader.Peek(path, opts)
}

// DetectLoader detects whether the environment is inline or static and picks
// the approriate loader
func detectLoader(base string) (Loader, error) {
func DetectLoader(path string) (Loader, error) {
_, base, err := jpath.Dirs(path)
if err != nil {
return nil, err
}

// check if spec.json exists
_, err := os.Stat(filepath.Join(base, spec.Specfile))
_, err = os.Stat(filepath.Join(base, spec.Specfile))
if os.IsNotExist(err) {
return &InlineLoader{}, nil
} else if err != nil {
Expand All @@ -60,7 +71,11 @@ func detectLoader(base string) (Loader, error) {

// Loader is an abstraction over the process of loading Environments
type Loader interface {
// Load the environment with path
Load(path string, opts JsonnetOpts) (*v1alpha1.Environment, error)

// Peek only loads metadata and omits the actual resources
Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error)
}

type LoadResult struct {
Expand Down
17 changes: 13 additions & 4 deletions pkg/tanka/static.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,31 @@ import (
type StaticLoader struct{}

func (s StaticLoader) Load(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
root, base, err := jpath.Dirs(path)
config, err := Peek(path, opts)
if err != nil {
return nil, err
}

config, err := parseStaticSpec(root, base)
data, err := EvalJsonnet(path, opts)
if err != nil {
return nil, err
}

data, err := EvalJsonnet(path, opts)
if err := json.Unmarshal([]byte(data), &config.Data); err != nil {
return nil, err
}

return config, nil
}

func (s StaticLoader) Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
root, base, err := jpath.Dirs(path)
if err != nil {
return nil, err
}

if err := json.Unmarshal([]byte(data), &config.Data); err != nil {
config, err := parseStaticSpec(root, base)
if err != nil {
return nil, err
}

Expand Down

0 comments on commit e5b5266

Please sign in to comment.