From ccd74079a98f48ebfd8e1f24d04ff541cdefa8ff Mon Sep 17 00:00:00 2001 From: Alex Clemmer <clemmer.alexander@gmail.com> Date: Wed, 30 Aug 2017 11:42:00 +0100 Subject: [PATCH] Generate ksonnet-lib as part of `metadata.Manager` initialization `metadata.Init` is meant to initialize a ksonnet application, including its directory structure and the initial versions of various metadata files in the tree. But, this implementation is incomplete: currently only the directory tree is initialized. This commit will change init to generate ksonnet-lib as part of the initialization process. --- metadata/manager.go | 48 +++++++++++++++++++++++++++++++++++++--- metadata/manager_test.go | 28 ++++++++++++++++++++++- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/metadata/manager.go b/metadata/manager.go index 9898bfed..7f606878 100644 --- a/metadata/manager.go +++ b/metadata/manager.go @@ -1,11 +1,14 @@ package metadata import ( + "encoding/json" "fmt" "os" "path" "path/filepath" + "github.com/ksonnet/ksonnet-lib/ksonnet-gen/ksonnet" + "github.com/ksonnet/ksonnet-lib/ksonnet-gen/kubespec" "github.com/spf13/afero" ) @@ -24,7 +27,8 @@ const ( schemaDir = "vendor/schema" vendorLibDir = "vendor/lib" - schemaFilename = "swagger.json" + schemaFilename = "swagger.json" + ksonnetLibCoreFilename = "k8s.libsonnet" ) type manager struct { @@ -62,18 +66,41 @@ func findManager(abs AbsPath, appFS afero.Fs) (*manager, error) { } func initManager(rootPath AbsPath, spec ClusterSpec, appFS afero.Fs) (*manager, error) { - data, err := spec.data() + // + // IMPLEMENTATION NOTE: We get the cluster specification and generate + // ksonnet-lib before initializing the directory structure so that failure of + // either (e.g., GET'ing the spec from a live cluster returns 404) does not + // result in a partially-initialized directory structure. + // + + // Get cluster specification data, possibly from the network. + specData, err := spec.data() if err != nil { return nil, err } m := newManager(rootPath, appFS) + // Generate the program text for ksonnet-lib. + ksonnetLibDir := appendToAbsPath(m.schemaDir, defaultEnvName) + ksonnetLibData, err := generateKsonnetLibData(ksonnetLibDir, specData) + if err != nil { + return nil, err + } + + // Initialize directory structure. if err = m.createAppDirTree(); err != nil { return nil, err } - if err = m.cacheClusterSpecData(defaultEnvName, data); err != nil { + // Cache specification data. + if err = m.cacheClusterSpecData(defaultEnvName, specData); err != nil { + return nil, err + } + + ksonnetLibPath := appendToAbsPath(ksonnetLibDir, ksonnetLibCoreFilename) + err = afero.WriteFile(appFS, string(ksonnetLibPath), ksonnetLibData, 0644) + if err != nil { return nil, err } @@ -136,3 +163,18 @@ func (m *manager) createAppDirTree() error { return nil } + +func generateKsonnetLibData(ksonnetLibDir AbsPath, text []byte) ([]byte, error) { + // Deserialize the API object. + s := kubespec.APISpec{} + err := json.Unmarshal(text, &s) + if err != nil { + return nil, err + } + + s.Text = text + s.FilePath = filepath.Dir(string(ksonnetLibDir)) + + // Emit Jsonnet code. + return ksonnet.Emit(&s, nil, nil) +} diff --git a/metadata/manager_test.go b/metadata/manager_test.go index 1329bc8b..d73fd97c 100644 --- a/metadata/manager_test.go +++ b/metadata/manager_test.go @@ -10,7 +10,25 @@ import ( const ( blankSwagger = "/blankSwagger.json" - blankSwaggerData = `{}` + blankSwaggerData = `{ + "swagger": "2.0", + "info": { + "title": "Kubernetes", + "version": "v1.7.0" + }, + "paths": { + }, + "definitions": { + } +}` + blankKsonnetLib = `// AUTOGENERATED from the Kubernetes OpenAPI specification. DO NOT MODIFY. +// Kubernetes version: v1.7.0 + +{ + local hidden = { + }, +} +` ) var appFS = afero.NewMemMapFs() @@ -60,6 +78,14 @@ func TestInitSuccess(t *testing.T) { } else if actualSwagger := string(bytes); actualSwagger != blankSwaggerData { t.Fatalf("Expected swagger file at '%s' to have value: '%s', got: '%s'", schemaPath, blankSwaggerData, actualSwagger) } + + ksonnetLibPath := appendToAbsPath(envPath, ksonnetLibCoreFilename) + ksonnetLibBytes, err := afero.ReadFile(appFS, string(ksonnetLibPath)) + if err != nil { + t.Fatalf("Failed to read ksonnet-lib file at '%s':\n%v", ksonnetLibPath, err) + } else if actualKsonnetLib := string(ksonnetLibBytes); actualKsonnetLib != blankKsonnetLib { + t.Fatalf("Expected swagger file at '%s' to have value: '%s', got: '%s'", ksonnetLibPath, blankKsonnetLib, actualKsonnetLib) + } } func TestFindSuccess(t *testing.T) { -- GitLab