From 74fffc82baa88ee2d402c58df6b8e048422efabc Mon Sep 17 00:00:00 2001 From: Torin Sandall Date: Fri, 15 Feb 2019 13:25:59 -0800 Subject: [PATCH] internal: Add helper package to store manifests Previously we had a bunch of ad-hoc code to store the revision and roots internally. These changes just add a proper package to deal with the reading and writing of the revision and roots. Note, the bundle package itself is still hardcoding the manifest path but we can fix that in a subsequent PR. Signed-off-by: Torin Sandall --- internal/manifest/manifest.go | 82 +++++++++++++++++++++++++++++++++++ plugins/bundle/plugin.go | 53 ++-------------------- 2 files changed, 86 insertions(+), 49 deletions(-) create mode 100644 internal/manifest/manifest.go diff --git a/internal/manifest/manifest.go b/internal/manifest/manifest.go new file mode 100644 index 0000000000..4387008f8d --- /dev/null +++ b/internal/manifest/manifest.go @@ -0,0 +1,82 @@ +// Copyright 2019 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package manifest implements helper functions for the stored manifest. +package manifest + +import ( + "context" + "fmt" + + "github.com/open-policy-agent/opa/bundle" + "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/util" +) + +var bundlePath = storage.MustParsePath("/system/bundle") +var manifestPath = storage.MustParsePath("/system/bundle/manifest") +var revisionPath = storage.MustParsePath("/system/bundle/manifest/revision") +var rootsPath = storage.MustParsePath("/system/bundle/manifest/roots") + +// Write the manifest into the storage. This function is called when +// the bundle is activated. +func Write(ctx context.Context, store storage.Store, txn storage.Transaction, m bundle.Manifest) error { + + var value interface{} = m + + if err := util.RoundTrip(&value); err != nil { + return err + } + + if err := storage.MakeDir(ctx, store, txn, bundlePath); err != nil { + return err + } + + return store.Write(ctx, txn, storage.AddOp, manifestPath, value) +} + +// ReadBundleRoots returns the roots specified in the currently +// activated bundle. If there is no activated bundle, this function +// will return storage NotFound error. +func ReadBundleRoots(ctx context.Context, store storage.Store, txn storage.Transaction) ([]string, error) { + + value, err := store.Read(ctx, txn, rootsPath) + if err != nil { + return nil, err + } + + sl, ok := value.([]interface{}) + if !ok { + return nil, fmt.Errorf("corrupt manifest roots") + } + + roots := make([]string, len(sl)) + + for i := range sl { + roots[i], ok = sl[i].(string) + if !ok { + return nil, fmt.Errorf("corrupt manifest root") + } + } + + return roots, nil +} + +// ReadBundleRevision returns the revision in the currently activated +// bundle. If there is no activated bundle, ths function will return +// storage NotFound error. +func ReadBundleRevision(ctx context.Context, store storage.Store, txn storage.Transaction) (string, error) { + + value, err := store.Read(ctx, txn, revisionPath) + if err != nil { + return "", err + } + + str, ok := value.(string) + if !ok { + return "", fmt.Errorf("corrupt manifest revision") + } + + return str, nil +} diff --git a/plugins/bundle/plugin.go b/plugins/bundle/plugin.go index a0679b2bd9..6579a78a39 100644 --- a/plugins/bundle/plugin.go +++ b/plugins/bundle/plugin.go @@ -15,9 +15,9 @@ import ( "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/bundle" "github.com/open-policy-agent/opa/download" + "github.com/open-policy-agent/opa/internal/manifest" "github.com/open-policy-agent/opa/plugins" "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/util" "github.com/sirupsen/logrus" ) @@ -195,7 +195,7 @@ func (p *Plugin) activate(ctx context.Context, b *bundle.Bundle) error { } } - if roots, err := p.readRoots(ctx, txn); err == nil { + if roots, err := manifest.ReadBundleRoots(ctx, p.manager.Store, txn); err == nil { for _, root := range roots { erase[root] = struct{}{} } @@ -217,11 +217,11 @@ func (p *Plugin) activate(ctx context.Context, b *bundle.Bundle) error { return err } - if err := p.writeManifest(ctx, txn, b.Manifest); err != nil { + if err := p.writeModules(ctx, txn, b.Modules); err != nil { return err } - if err := p.writeModules(ctx, txn, b.Modules); err != nil { + if err := manifest.Write(ctx, p.manager.Store, txn, b.Manifest); err != nil { return err } @@ -314,45 +314,6 @@ func (p *Plugin) writeModules(ctx context.Context, txn storage.Transaction, file return nil } -func (p *Plugin) readRoots(ctx context.Context, txn storage.Transaction) ([]string, error) { - - value, err := p.manager.Store.Read(ctx, txn, rootsPath) - if err != nil { - return nil, err - } - - sl, ok := value.([]interface{}) - if !ok { - return nil, fmt.Errorf("corrupt manifest roots") - } - - roots := make([]string, len(sl)) - - for i := range sl { - roots[i], ok = sl[i].(string) - if !ok { - return nil, fmt.Errorf("corrupt manifest root") - } - } - - return roots, nil -} - -func (p *Plugin) writeManifest(ctx context.Context, txn storage.Transaction, m bundle.Manifest) error { - - var value interface{} = m - - if err := util.RoundTrip(&value); err != nil { - return err - } - - if err := storage.MakeDir(ctx, p.manager.Store, txn, bundlePath); err != nil { - return err - } - - return p.manager.Store.Write(ctx, txn, storage.AddOp, manifestPath, value) -} - func (p *Plugin) logError(fmt string, a ...interface{}) { logrus.WithFields(p.logrusFields()).Errorf(fmt, a...) } @@ -372,12 +333,6 @@ func (p *Plugin) logrusFields() logrus.Fields { } } -var ( - bundlePath = storage.MustParsePath("/system/bundle") - manifestPath = storage.MustParsePath("/system/bundle/manifest") - rootsPath = storage.MustParsePath("/system/bundle/manifest/roots") -) - func lookup(path storage.Path, data map[string]interface{}) (interface{}, bool) { if len(path) == 0 { return data, true