diff --git a/constraint/pkg/client/backend.go b/constraint/pkg/client/backend.go index 4a58d165c..ebe64b69f 100644 --- a/constraint/pkg/client/backend.go +++ b/constraint/pkg/client/backend.go @@ -1,7 +1,7 @@ package client import ( - "context" + "errors" "fmt" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" @@ -23,10 +23,8 @@ func Driver(d drivers.Driver) BackendOpt { } } -// NewBackend creates a new backend. A backend could be a connection to a remote -// server or a new local OPA instance. -// -// A BackendOpt setting driver, such as Driver() must be passed. +// NewBackend creates a new backend. A backend could be a connection to a remote server or +// a new local OPA instance. func NewBackend(opts ...BackendOpt) (*Backend, error) { helper, err := newCRDHelper() if err != nil { @@ -38,17 +36,16 @@ func NewBackend(opts ...BackendOpt) (*Backend, error) { } if b.driver == nil { - return nil, fmt.Errorf("%w: no driver supplied", ErrCreatingBackend) + return nil, errors.New("no driver supplied to the backend") } return b, nil } // NewClient creates a new client for the supplied backend. -func (b *Backend) NewClient(ctx context.Context, opts ...Opt) (*Client, error) { +func (b *Backend) NewClient(opts ...Opt) (*Client, error) { if b.hasClient { - return nil, fmt.Errorf("%w: only one client per backend is allowed", - ErrCreatingClient) + return nil, errors.New("currently only one client per backend is supported") } var fields []string @@ -63,32 +60,32 @@ func (b *Backend) NewClient(ctx context.Context, opts ...Opt) (*Client, error) { allowedDataFields: fields, } + var errs Errors for _, opt := range opts { if err := opt(c); err != nil { - return nil, err + errs = append(errs, err) } } + if len(errs) > 0 { + return nil, errs + } for _, field := range c.allowedDataFields { if !validDataFields[field] { - return nil, fmt.Errorf("%w: invalid data field %q; allowed fields are: %v", - ErrCreatingClient, field, validDataFields) + return nil, fmt.Errorf("invalid data field %s", field) } } if len(c.targets) == 0 { - return nil, fmt.Errorf("%w: must specify at least one target with client.Targets", - ErrCreatingClient) + return nil, errors.New("no targets registered: please register a target via client.Targets()") } - if err := b.driver.Init(ctx); err != nil { + if err := b.driver.Init(); err != nil { return nil, err } - if err := c.init(ctx); err != nil { + if err := c.init(); err != nil { return nil, err } - - b.hasClient = true return c, nil } diff --git a/constraint/pkg/client/client.go b/constraint/pkg/client/client.go index 4e4fd2750..d3aef1a47 100644 --- a/constraint/pkg/client/client.go +++ b/constraint/pkg/client/client.go @@ -6,12 +6,11 @@ import ( "errors" "fmt" "path" - "sort" + "regexp" "strings" "sync" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" "github.com/open-policy-agent/frameworks/constraint/pkg/client/regolib" constraintlib "github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" @@ -25,6 +24,46 @@ import ( const constraintGroup = "constraints.gatekeeper.sh" +type Opt func(*Client) error + +// Client options + +var targetNameRegex = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9.]*$`) + +func Targets(ts ...TargetHandler) Opt { + return func(c *Client) error { + var errs Errors + handlers := make(map[string]TargetHandler, len(ts)) + for _, t := range ts { + name := t.GetName() + switch { + case name == "": + errs = append(errs, errors.New("invalid target: a target is returning an empty string for GetName()")) + case !targetNameRegex.MatchString(name): + errs = append(errs, fmt.Errorf("target name %q is not of the form %q", name, targetNameRegex.String())) + default: + handlers[name] = t + } + } + c.targets = handlers + + if len(errs) > 0 { + return errs + } + return nil + } +} + +// AllowedDataFields sets the fields under `data` that Rego in ConstraintTemplates +// can access. If unset, all fields can be accessed. Only fields recognized by +// the system can be enabled. +func AllowedDataFields(fields ...string) Opt { + return func(c *Client) error { + c.allowedDataFields = fields + return nil + } +} + type templateEntry struct { template *templates.ConstraintTemplate CRD *apiextensions.CustomResourceDefinition @@ -32,14 +71,11 @@ type templateEntry struct { } type Client struct { - backend *Backend - targets map[string]TargetHandler - - // mtx guards access to both templates and constraints. - mtx sync.RWMutex - templates map[templateKey]*templateEntry - constraints map[schema.GroupKind]map[string]*unstructured.Unstructured - + backend *Backend + targets map[string]TargetHandler + constraintsMux sync.RWMutex + templates map[templateKey]*templateEntry + constraints map[schema.GroupKind]map[string]*unstructured.Unstructured allowedDataFields []string } @@ -76,7 +112,7 @@ func (c *Client) AddData(ctx context.Context, data interface{}) (*types.Response if len(errMap) == 0 { return resp, nil } - return resp, &errMap + return resp, errMap } // RemoveData removes data from OPA for every target that can handle the data. @@ -103,7 +139,7 @@ func (c *Client) RemoveData(ctx context.Context, data interface{}) (*types.Respo if len(errMap) == 0 { return resp, nil } - return resp, &errMap + return resp, errMap } // createTemplatePath returns the package path for a given template: templates... @@ -122,14 +158,14 @@ func (c *Client) validateTargets(templ *templates.ConstraintTemplate) (*template return nil, nil, err } + if len(templ.Spec.Targets) != 1 { + return nil, nil, fmt.Errorf("expected exactly 1 item in targets, got %v", templ.Spec.Targets) + } + targetSpec := &templ.Spec.Targets[0] targetHandler, found := c.targets[targetSpec.Target] - if !found { - knownTargets := c.knownTargets() - - return nil, nil, fmt.Errorf("%w: target %s not recognized, known targets %v", - ErrInvalidConstraintTemplate, targetSpec.Target, knownTargets) + return nil, nil, fmt.Errorf("target %s not recognized", targetSpec.Target) } return targetSpec, targetHandler, nil @@ -161,10 +197,9 @@ func (a *rawCTArtifacts) Key() templateKey { // createRawTemplateArtifacts creates the "free" artifacts for a template, avoiding more // complex tasks like rewriting Rego. Provides minimal validation. func (c *Client) createRawTemplateArtifacts(templ *templates.ConstraintTemplate) (*rawCTArtifacts, error) { - if templ.GetName() == "" { - return nil, fmt.Errorf("%w: missing name", ErrInvalidConstraintTemplate) + if templ.ObjectMeta.Name == "" { + return nil, errors.New("invalid Template: missing name") } - return &rawCTArtifacts{template: templ}, nil } @@ -210,16 +245,8 @@ func (c *Client) createBasicTemplateArtifacts(templ *templates.ConstraintTemplat if err != nil { return nil, err } - - kind := templ.Spec.CRD.Spec.Names.Kind - if kind == "" { - return nil, fmt.Errorf("%w: ConstraintTemplate %q does not specify CRD Kind", - ErrInvalidConstraintTemplate, templ.GetName()) - } - - if !strings.EqualFold(templ.ObjectMeta.Name, kind) { - return nil, fmt.Errorf("%w: the ConstraintTemplate's name %q is not equal to the lowercase of CRD's Kind: %q", - ErrInvalidConstraintTemplate, templ.ObjectMeta.Name, strings.ToLower(kind)) + if !strings.EqualFold(templ.ObjectMeta.Name, templ.Spec.CRD.Spec.Names.Kind) { + return nil, fmt.Errorf("the ConstraintTemplate's name %q is not equal to the lowercase of CRD's Kind: %q", templ.ObjectMeta.Name, strings.ToLower(templ.Spec.CRD.Spec.Names.Kind)) } targetSpec, targetHandler, err := c.validateTargets(templ) @@ -231,14 +258,12 @@ func (c *Client) createBasicTemplateArtifacts(templ *templates.ConstraintTemplat if err != nil { return nil, err } - crd, err := c.backend.crd.createCRD(templ, sch) if err != nil { return nil, err } - if err = c.backend.crd.validateCRD(crd); err != nil { - return nil, fmt.Errorf("%w: %v", ErrInvalidConstraintTemplate, err) + return nil, err } entryPointPath := createTemplatePath(targetHandler.GetName(), templ.Spec.CRD.Spec.Names.Kind) @@ -267,63 +292,55 @@ func (c *Client) createTemplateArtifacts(templ *templates.ConstraintTemplate) (* } libPrefix := templateLibPrefix(artifacts.targetHandler.GetName(), artifacts.crd.Spec.Names.Kind) - rr, err := regorewriter.New( regorewriter.NewPackagePrefixer(libPrefix), []string{"data.lib"}, externs) if err != nil { - return nil, fmt.Errorf("creating rego rewriter: %w", err) + return nil, err } entryPoint, err := parseModule(artifacts.namePrefix, artifacts.targetSpec.Rego) if err != nil { - return nil, fmt.Errorf("%w: %v", ErrInvalidConstraintTemplate, err) + return nil, err } - if entryPoint == nil { - return nil, fmt.Errorf("%w: failed to parse module for unknown reason", - ErrInvalidConstraintTemplate) + return nil, fmt.Errorf("failed to parse module for unknown reason") } - if err = rewriteModulePackage(artifacts.namePrefix, entryPoint); err != nil { + if err := rewriteModulePackage(artifacts.namePrefix, entryPoint); err != nil { return nil, err } req := map[string]struct{}{"violation": {}} - if err = requireModuleRules(entryPoint, req); err != nil { - return nil, fmt.Errorf("%w: invalid rego: %v", - ErrInvalidConstraintTemplate, err) + if err := requireRulesModule(entryPoint, req); err != nil { + return nil, fmt.Errorf("invalid rego: %s", err) } rr.AddEntryPointModule(artifacts.namePrefix, entryPoint) for idx, libSrc := range artifacts.targetSpec.Libs { libPath := fmt.Sprintf(`%s["lib_%d"]`, libPrefix, idx) - if err = rr.AddLib(libPath, libSrc); err != nil { - return nil, fmt.Errorf("%w: %v", - ErrInvalidConstraintTemplate, err) + if err := rr.AddLib(libPath, libSrc); err != nil { + return nil, err } } sources, err := rr.Rewrite() if err != nil { - return nil, fmt.Errorf("%w: %v", - ErrInvalidConstraintTemplate, err) + return nil, err } var mods []string - err = sources.ForEachModule(func(m *regorewriter.Module) error { - content, err2 := m.Content() - if err2 != nil { - return err2 + if err := sources.ForEachModule(func(m *regorewriter.Module) error { + content, err := m.Content() + if err != nil { + return err } mods = append(mods, string(content)) return nil - }) - if err != nil { - return nil, fmt.Errorf("%w: %v", - ErrInvalidConstraintTemplate, err) + }); err != nil { + return nil, err } return &ctArtifacts{ @@ -333,12 +350,7 @@ func (c *Client) createTemplateArtifacts(templ *templates.ConstraintTemplate) (* } // CreateCRD creates a CRD from template. -func (c *Client) CreateCRD(_ context.Context, templ *templates.ConstraintTemplate) (*apiextensions.CustomResourceDefinition, error) { - if templ == nil { - return nil, fmt.Errorf("%w: got nil ConstraintTemplate", - ErrInvalidConstraintTemplate) - } - +func (c *Client) CreateCRD(templ *templates.ConstraintTemplate) (*apiextensions.CustomResourceDefinition, error) { artifacts, err := c.createTemplateArtifacts(templ) if err != nil { return nil, err @@ -349,7 +361,7 @@ func (c *Client) CreateCRD(_ context.Context, templ *templates.ConstraintTemplat // AddTemplate adds the template source code to OPA and registers the CRD with the client for // schema validation on calls to AddConstraint. On error, the responses return value // will still be populated so that partial results can be analyzed. -func (c *Client) AddTemplate(ctx context.Context, templ *templates.ConstraintTemplate) (*types.Responses, error) { +func (c *Client) AddTemplate(templ *templates.ConstraintTemplate) (*types.Responses, error) { resp := types.NewResponses() basicArtifacts, err := c.createBasicTemplateArtifacts(templ) @@ -358,7 +370,7 @@ func (c *Client) AddTemplate(ctx context.Context, templ *templates.ConstraintTem } // return immediately if no change - if cached, err := c.GetTemplate(ctx, templ); err == nil && cached.SemanticEqual(templ) { + if cached, err := c.GetTemplate(templ); err == nil && cached.SemanticEqual(templ) { resp.Handled[basicArtifacts.targetHandler.GetName()] = true return resp, nil } @@ -368,11 +380,11 @@ func (c *Client) AddTemplate(ctx context.Context, templ *templates.ConstraintTem return resp, err } - c.mtx.Lock() - defer c.mtx.Unlock() + c.constraintsMux.Lock() + defer c.constraintsMux.Unlock() - if err = c.backend.driver.PutModules(ctx, artifacts.namePrefix, artifacts.modules); err != nil { - return resp, fmt.Errorf("%w: %v", local.ErrCompile, err) + if err := c.backend.driver.PutModules(artifacts.namePrefix, artifacts.modules); err != nil { + return resp, err } cpy := templ.DeepCopy() @@ -401,12 +413,12 @@ func (c *Client) RemoveTemplate(ctx context.Context, templ *templates.Constraint return resp, err } - c.mtx.Lock() - defer c.mtx.Unlock() + c.constraintsMux.Lock() + defer c.constraintsMux.Unlock() - template, err := c.getTemplateNoLock(rawArtifacts.Key()) + template, err := c.getTemplateNoLock(rawArtifacts) if err != nil { - if errors.Is(err, ErrMissingConstraintTemplate) { + if IsMissingTemplateError(err) { return resp, nil } return resp, err @@ -417,7 +429,7 @@ func (c *Client) RemoveTemplate(ctx context.Context, templ *templates.Constraint return resp, err } - if _, err := c.backend.driver.DeleteModules(ctx, artifacts.namePrefix); err != nil { + if _, err := c.backend.driver.DeleteModules(artifacts.namePrefix); err != nil { return resp, err } @@ -438,24 +450,22 @@ func (c *Client) RemoveTemplate(ctx context.Context, templ *templates.Constraint } // GetTemplate gets the currently recognized template. -func (c *Client) GetTemplate(_ context.Context, templ *templates.ConstraintTemplate) (*templates.ConstraintTemplate, error) { +func (c *Client) GetTemplate(templ *templates.ConstraintTemplate) (*templates.ConstraintTemplate, error) { artifacts, err := c.createRawTemplateArtifacts(templ) if err != nil { return nil, err } - c.mtx.RLock() - defer c.mtx.RUnlock() - return c.getTemplateNoLock(artifacts.Key()) + c.constraintsMux.Lock() + defer c.constraintsMux.Unlock() + return c.getTemplateNoLock(artifacts) } -func (c *Client) getTemplateNoLock(key templateKey) (*templates.ConstraintTemplate, error) { - t, ok := c.templates[key] +func (c *Client) getTemplateNoLock(artifacts keyableArtifact) (*templates.ConstraintTemplate, error) { + t, ok := c.templates[artifacts.Key()] if !ok { - return nil, fmt.Errorf("%w: template for %q not found", - ErrMissingConstraintTemplate, key) + return nil, NewMissingTemplateError(string(artifacts.Key())) } - ret := t.template.DeepCopy() return ret, nil } @@ -464,20 +474,15 @@ func (c *Client) getTemplateNoLock(key templateKey) (*templates.ConstraintTempla // for each target: cluster.... func createConstraintSubPath(constraint *unstructured.Unstructured) (string, error) { if constraint.GetName() == "" { - return "", fmt.Errorf("%w: missing name", ErrInvalidConstraint) + return "", errors.New("invalid Constraint: missing name") } - gvk := constraint.GroupVersionKind() if gvk.Group == "" { - return "", fmt.Errorf("%w: empty group for constrant %q", - ErrInvalidConstraint, constraint.GetName()) + return "", fmt.Errorf("empty group for the constrant named %s", constraint.GetName()) } - if gvk.Kind == "" { - return "", fmt.Errorf("%w: empty kind for constraint %q", - ErrInvalidConstraint, constraint.GetName()) + return "", fmt.Errorf("empty kind for the constraint named %s", constraint.GetName()) } - return path.Join(createConstraintGKSubPath(gvk.GroupKind()), constraint.GetName()), nil } @@ -510,31 +515,19 @@ func constraintPathMerge(target, subpath string) string { func (c *Client) getTemplateEntry(constraint *unstructured.Unstructured, lock bool) (*templateEntry, error) { kind := constraint.GetKind() if kind == "" { - return nil, fmt.Errorf("%w: kind missing from Constraint %q", - ErrInvalidConstraint, constraint.GetName()) + return nil, fmt.Errorf("kind missing from Constraint %q", constraint.GetName()) } - if constraint.GroupVersionKind().Group != constraintGroup { - return nil, fmt.Errorf("%w: wrong API Group for Constraint %q, need %q", - ErrInvalidConstraint, constraint.GetName(), constraintGroup) + return nil, fmt.Errorf("wrong API Group for Constraint %q", constraint.GetName()) } - if lock { - c.mtx.RLock() - defer c.mtx.RUnlock() + c.constraintsMux.RLock() + defer c.constraintsMux.RUnlock() } - entry, ok := c.templates[templateKeyFromConstraint(constraint)] if !ok { - var known []string - for k := range c.templates { - known = append(known, string(k)) - } - - return nil, fmt.Errorf("%w: Constraint kind %q is not recognized, known kinds %v", - ErrMissingConstraintTemplate, kind, known) + return nil, NewUnrecognizedConstraintError(kind) } - return entry, nil } @@ -542,30 +535,25 @@ func (c *Client) getTemplateEntry(constraint *unstructured.Unstructured, lock bo // On error, the responses return value will still be populated so that // partial results can be analyzed. func (c *Client) AddConstraint(ctx context.Context, constraint *unstructured.Unstructured) (*types.Responses, error) { - c.mtx.Lock() - defer c.mtx.Unlock() - + c.constraintsMux.RLock() + defer c.constraintsMux.RUnlock() resp := types.NewResponses() errMap := make(ErrorMap) entry, err := c.getTemplateEntry(constraint, false) if err != nil { return resp, err } - subPath, err := createConstraintSubPath(constraint) if err != nil { - return resp, fmt.Errorf("creating Constraint subpath: %w", err) + return resp, err } - // return immediately if no change - cached, err := c.getConstraintNoLock(constraint) - if err == nil && constraintlib.SemanticEqual(cached, constraint) { + if cached, err := c.getConstraintNoLock(constraint); err == nil && constraintlib.SemanticEqual(cached, constraint) { for _, target := range entry.Targets { resp.Handled[target] = true } return resp, nil } - if err := c.validateConstraint(constraint, false); err != nil { return resp, err } @@ -583,21 +571,18 @@ func (c *Client) AddConstraint(ctx context.Context, constraint *unstructured.Uns } resp.Handled[target] = true } - if len(errMap) == 0 { c.constraints[constraint.GroupVersionKind().GroupKind()][subPath] = constraint.DeepCopy() return resp, nil } - - return resp, &errMap + return resp, errMap } // RemoveConstraint removes a constraint from OPA. On error, the responses // return value will still be populated so that partial results can be analyzed. func (c *Client) RemoveConstraint(ctx context.Context, constraint *unstructured.Unstructured) (*types.Responses, error) { - c.mtx.Lock() - defer c.mtx.Unlock() - + c.constraintsMux.RLock() + defer c.constraintsMux.RUnlock() return c.removeConstraintNoLock(ctx, constraint) } @@ -631,7 +616,7 @@ func (c *Client) removeConstraintNoLock(ctx context.Context, constraint *unstruc delete(c.constraints[constraint.GroupVersionKind().GroupKind()], subPath) return resp, nil } - return resp, &errMap + return resp, errMap } // getConstraintNoLock gets the currently recognized constraint without the lock. @@ -641,20 +626,17 @@ func (c *Client) getConstraintNoLock(constraint *unstructured.Unstructured) (*un return nil, err } - gk := constraint.GroupVersionKind().GroupKind() - cstr, ok := c.constraints[gk][subPath] + cstr, ok := c.constraints[constraint.GroupVersionKind().GroupKind()][subPath] if !ok { - return nil, fmt.Errorf("%w %v %q", - ErrMissingConstraint, gk, constraint.GetName()) + return nil, NewMissingConstraintError(subPath) } return cstr.DeepCopy(), nil } // GetConstraint gets the currently recognized constraint. -func (c *Client) GetConstraint(_ context.Context, constraint *unstructured.Unstructured) (*unstructured.Unstructured, error) { - c.mtx.RLock() - defer c.mtx.RUnlock() - +func (c *Client) GetConstraint(constraint *unstructured.Unstructured) (*unstructured.Unstructured, error) { + c.constraintsMux.Lock() + defer c.constraintsMux.Unlock() return c.getConstraintNoLock(constraint) } @@ -679,12 +661,12 @@ func (c *Client) validateConstraint(constraint *unstructured.Unstructured, lock // ValidateConstraint returns an error if the constraint is not recognized or does not conform to // the registered CRD for that constraint. -func (c *Client) ValidateConstraint(_ context.Context, constraint *unstructured.Unstructured) error { +func (c *Client) ValidateConstraint(constraint *unstructured.Unstructured) error { return c.validateConstraint(constraint, true) } // init initializes the OPA backend for the client. -func (c *Client) init(ctx context.Context) error { +func (c *Client) init() error { for _, t := range c.targets { hooks := fmt.Sprintf(`hooks["%s"]`, t.GetName()) templMap := map[string]string{"Target": t.GetName()} @@ -694,18 +676,16 @@ func (c *Client) init(ctx context.Context) error { return err } - builtinPath := fmt.Sprintf("%s.hooks_builtin", hooks) - err := c.backend.driver.PutModule(context.Background(), builtinPath, libBuiltin.String()) + moduleName := fmt.Sprintf("%s.hooks_builtin", hooks) + err := c.backend.driver.PutModule(moduleName, libBuiltin.String()) if err != nil { return err } libTempl := t.Library() if libTempl == nil { - return fmt.Errorf("%w: target %q has no Rego library template", - ErrCreatingClient, t.GetName()) + return fmt.Errorf("target %q has no Rego library template", t.GetName()) } - libBuf := &bytes.Buffer{} if err := libTempl.Execute(libBuf, map[string]string{ "ConstraintsRoot": fmt.Sprintf(`data.constraints["%s"].cluster["%s"]`, t.GetName(), constraintGroup), @@ -713,41 +693,30 @@ func (c *Client) init(ctx context.Context) error { }); err != nil { return err } - lib := libBuf.String() req := map[string]struct{}{ "autoreject_review": {}, "matching_reviews_and_constraints": {}, "matching_constraints": {}, } - modulePath := fmt.Sprintf("%s.library", hooks) libModule, err := parseModule(modulePath, lib) if err != nil { return fmt.Errorf("failed to parse module: %w", err) } - - err = requireModuleRules(libModule, req) - if err != nil { - return fmt.Errorf("problem with the below Rego for %q target:\n\n====%s\n====\n%w", - t.GetName(), lib, err) + if err := requireRulesModule(libModule, req); err != nil { + return fmt.Errorf("problem with the below Rego for %q target:\n\n====%s\n====\n%s", t.GetName(), lib, err) } - err = rewriteModulePackage(modulePath, libModule) if err != nil { return err } - src, err := format.Ast(libModule) if err != nil { - return fmt.Errorf("%w: could not re-format Rego source: %v", - ErrCreatingClient, err) + return fmt.Errorf("could not re-format Rego source: %v", err) } - - err = c.backend.driver.PutModule(context.TODO(), modulePath, string(src)) - if err != nil { - return fmt.Errorf("%w: error %s from compiled source:\n%s", - ErrCreatingClient, err, src) + if err := c.backend.driver.PutModule(modulePath, string(src)); err != nil { + return fmt.Errorf("error %s from compiled source:\n%s", err, src) } } @@ -756,9 +725,8 @@ func (c *Client) init(ctx context.Context) error { // Reset the state of OPA. func (c *Client) Reset(ctx context.Context) error { - c.mtx.Lock() - defer c.mtx.Unlock() - + c.constraintsMux.Lock() + defer c.constraintsMux.Unlock() for name := range c.targets { if _, err := c.backend.driver.DeleteData(ctx, fmt.Sprintf("/external/%s", name)); err != nil { return err @@ -769,7 +737,7 @@ func (c *Client) Reset(ctx context.Context) error { } for name, v := range c.templates { for _, t := range v.Targets { - if _, err := c.backend.driver.DeleteModule(ctx, fmt.Sprintf(`templates["%s"]["%s"]`, t, name)); err != nil { + if _, err := c.backend.driver.DeleteModule(fmt.Sprintf(`templates["%s"]["%s"]`, t, name)); err != nil { return err } } @@ -779,6 +747,18 @@ func (c *Client) Reset(ctx context.Context) error { return nil } +type queryCfg struct { + enableTracing bool +} + +type QueryOpt func(*queryCfg) + +func Tracing(enabled bool) QueryOpt { + return func(cfg *queryCfg) { + cfg.enableTracing = enabled + } +} + // Review makes sure the provided object satisfies all stored constraints. // On error, the responses return value will still be populated so that // partial results can be analyzed. @@ -818,7 +798,7 @@ TargetLoop: if len(errMap) == 0 { return responses, nil } - return responses, &errMap + return responses, errMap } // Audit makes sure the cached state of the system satisfies all stored constraints. @@ -851,21 +831,10 @@ TargetLoop: if len(errMap) == 0 { return responses, nil } - return responses, &errMap + return responses, errMap } // Dump dumps the state of OPA to aid in debugging. func (c *Client) Dump(ctx context.Context) (string, error) { return c.backend.driver.Dump(ctx) } - -// knownTargets returns a sorted list of currently-known target names. -func (c *Client) knownTargets() []string { - var knownTargets []string - for known := range c.targets { - knownTargets = append(knownTargets, known) - } - sort.Strings(knownTargets) - - return knownTargets -} diff --git a/constraint/pkg/client/client_addtemplate_bench_test.go b/constraint/pkg/client/client_addtemplate_bench_test.go index ad7f7028d..c7edaf43a 100644 --- a/constraint/pkg/client/client_addtemplate_bench_test.go +++ b/constraint/pkg/client/client_addtemplate_bench_test.go @@ -1,7 +1,6 @@ package client import ( - "context" "fmt" "testing" @@ -82,7 +81,6 @@ func BenchmarkClient_AddTemplate(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - ctx := context.Background() targets := Targets(&handler{}) d := local.New() @@ -92,7 +90,7 @@ func BenchmarkClient_AddTemplate(b *testing.B) { b.Fatal(err) } - c, err := backend.NewClient(ctx, targets) + c, err := backend.NewClient(targets) if err != nil { b.Fatal(err) } @@ -100,7 +98,7 @@ func BenchmarkClient_AddTemplate(b *testing.B) { b.StartTimer() for _, ct := range cts { - _, _ = c.AddTemplate(ctx, ct) + _, _ = c.AddTemplate(ct) } } }) diff --git a/constraint/pkg/client/drivers/interface.go b/constraint/pkg/client/drivers/interface.go index 4d8918ce3..fdd06397a 100644 --- a/constraint/pkg/client/drivers/interface.go +++ b/constraint/pkg/client/drivers/interface.go @@ -19,16 +19,16 @@ func Tracing(enabled bool) QueryOpt { } type Driver interface { - Init(ctx context.Context) error + Init() error - PutModule(ctx context.Context, name string, src string) error + PutModule(name string, src string) error // PutModules upserts a number of modules under a given prefix. - PutModules(ctx context.Context, namePrefix string, srcs []string) error - DeleteModule(ctx context.Context, name string) (bool, error) + PutModules(namePrefix string, srcs []string) error + DeleteModule(name string) (bool, error) // DeleteModules deletes all modules under a given prefix and returns the // count of modules deleted. Deletion of non-existing prefix will // result in 0, nil being returned. - DeleteModules(ctx context.Context, namePrefix string) (int, error) + DeleteModules(namePrefix string) (int, error) PutData(ctx context.Context, path string, data interface{}) error DeleteData(ctx context.Context, path string) (bool, error) diff --git a/constraint/pkg/client/drivers/local/local.go b/constraint/pkg/client/drivers/local/local.go index 31e1db283..4efeabae4 100644 --- a/constraint/pkg/client/drivers/local/local.go +++ b/constraint/pkg/client/drivers/local/local.go @@ -70,7 +70,7 @@ type driver struct { providerCache *externaldata.ProviderCache } -func (d *driver) Init(ctx context.Context) error { +func (d *driver) Init() error { if d.providerCache != nil { rego.RegisterBuiltin1( ®o.Function{ @@ -168,7 +168,7 @@ func toModuleSetName(prefix string, idx int) string { return fmt.Sprintf("%s%d", toModuleSetPrefix(prefix), idx) } -func (d *driver) PutModule(ctx context.Context, name string, src string) error { +func (d *driver) PutModule(name string, src string) error { if err := d.checkModuleName(name); err != nil { return err } @@ -181,12 +181,12 @@ func (d *driver) PutModule(ctx context.Context, name string, src string) error { d.modulesMux.Lock() defer d.modulesMux.Unlock() - _, err := d.alterModules(ctx, insert, nil) + _, err := d.alterModules(insert, nil) return err } // PutModules implements drivers.Driver. -func (d *driver) PutModules(ctx context.Context, namePrefix string, srcs []string) error { +func (d *driver) PutModules(namePrefix string, srcs []string) error { if err := d.checkModuleSetName(namePrefix); err != nil { return err } @@ -210,13 +210,13 @@ func (d *driver) PutModules(ctx context.Context, namePrefix string, srcs []strin } } - _, err := d.alterModules(ctx, insert, remove) + _, err := d.alterModules(insert, remove) return err } // DeleteModule deletes a rule from OPA. Returns true if a rule was found and deleted, false // if a rule was not found, and any errors. -func (d *driver) DeleteModule(ctx context.Context, name string) (bool, error) { +func (d *driver) DeleteModule(name string) (bool, error) { if err := d.checkModuleName(name); err != nil { return false, err } @@ -228,7 +228,7 @@ func (d *driver) DeleteModule(ctx context.Context, name string) (bool, error) { return false, nil } - count, err := d.alterModules(ctx, nil, []string{name}) + count, err := d.alterModules(nil, []string{name}) return count == 1, err } @@ -236,7 +236,10 @@ func (d *driver) DeleteModule(ctx context.Context, name string) (bool, error) { // alterModules alters the modules in the driver by inserting and removing // the provided modules then returns the count of modules removed. // alterModules expects that the caller is holding the modulesMux lock. -func (d *driver) alterModules(ctx context.Context, insert insertParam, remove []string) (int, error) { +func (d *driver) alterModules(insert insertParam, remove []string) (int, error) { + // TODO(davis-haba): Remove this Context once it is no longer necessary. + ctx := context.TODO() + updatedModules := copyModules(d.modules) for _, name := range remove { delete(updatedModules, name) @@ -284,7 +287,7 @@ func (d *driver) alterModules(ctx context.Context, insert insertParam, remove [] } // DeleteModules implements drivers.Driver. -func (d *driver) DeleteModules(ctx context.Context, namePrefix string) (int, error) { +func (d *driver) DeleteModules(namePrefix string) (int, error) { if err := d.checkModuleSetName(namePrefix); err != nil { return 0, err } @@ -292,7 +295,7 @@ func (d *driver) DeleteModules(ctx context.Context, namePrefix string) (int, err d.modulesMux.Lock() defer d.modulesMux.Unlock() - return d.alterModules(ctx, nil, d.listModuleSet(namePrefix)) + return d.alterModules(nil, d.listModuleSet(namePrefix)) } // listModuleSet returns the list of names corresponding to a given module diff --git a/constraint/pkg/client/drivers/local/local_benchmark_test.go b/constraint/pkg/client/drivers/local/local_benchmark_test.go index 94fa13b35..2154ec13b 100644 --- a/constraint/pkg/client/drivers/local/local_benchmark_test.go +++ b/constraint/pkg/client/drivers/local/local_benchmark_test.go @@ -1,7 +1,6 @@ package local import ( - "context" "fmt" "testing" ) @@ -11,13 +10,12 @@ func BenchmarkDriver_PutModule(b *testing.B) { b.Run(fmt.Sprintf("%d templates", n), func(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - ctx := context.Background() d := New() b.StartTimer() for j := 0; j < n; j++ { name := fmt.Sprintf("foo-%d", j) - err := d.PutModule(ctx, name, Module) + err := d.PutModule(name, Module) if err != nil { b.Fatal(err) } diff --git a/constraint/pkg/client/drivers/local/local_test.go b/constraint/pkg/client/drivers/local/local_test.go index 747469a7b..6e707fd68 100644 --- a/constraint/pkg/client/drivers/local/local_test.go +++ b/constraint/pkg/client/drivers/local/local_test.go @@ -88,7 +88,7 @@ func (tt *compositeTestCase) run(t *testing.T) { switch a.Op { case addModule: for _, r := range a.Rules { - err := d.PutModule(ctx, r.Path, r.Content) + err := d.PutModule(r.Path, r.Content) if (err == nil) && a.ErrorExpected { t.Fatalf("PUT err = nil; want non-nil") } @@ -99,7 +99,7 @@ func (tt *compositeTestCase) run(t *testing.T) { case deleteModule: for _, r := range a.Rules { - b, err := d.DeleteModule(ctx, r.Path) + b, err := d.DeleteModule(r.Path) if (err == nil) && a.ErrorExpected { t.Fatalf("DELETE err = nil; want non-nil") } @@ -112,7 +112,7 @@ func (tt *compositeTestCase) run(t *testing.T) { } case putModules: - err := d.PutModules(ctx, a.RuleNamePrefix, a.Rules.srcs()) + err := d.PutModules(a.RuleNamePrefix, a.Rules.srcs()) if (err == nil) && a.ErrorExpected { t.Fatalf("PutModules err = nil; want non-nil") } @@ -121,7 +121,7 @@ func (tt *compositeTestCase) run(t *testing.T) { } case deleteModules: - count, err := d.DeleteModules(ctx, a.RuleNamePrefix) + count, err := d.DeleteModules(a.RuleNamePrefix) if (err == nil) && a.ErrorExpected { t.Fatalf("DeleteModules err = nil; want non-nil") } @@ -407,9 +407,7 @@ func TestPutModule(t *testing.T) { } for _, r := range tt.Rules { - ctx := context.Background() - - err := d.PutModule(ctx, r.Path, r.Content) + err := d.PutModule(r.Path, r.Content) if (err == nil) && tt.ErrorExpected { t.Fatalf("err = nil; want non-nil") } @@ -687,7 +685,7 @@ func TestQuery(t *testing.T) { } } - if err := d.PutModule(ctx, "test", `package hooks violation[r] { r = data.constraints[_] }`); err != nil { + if err := d.PutModule("test", `package hooks violation[r] { r = data.constraints[_] }`); err != nil { t.Fatal(err) } res, err := d.Query(ctx, "hooks.violation", nil) diff --git a/constraint/pkg/client/drivers/local/local_unit_test.go b/constraint/pkg/client/drivers/local/local_unit_test.go index d3c2f7ba5..6ea5ab3c8 100644 --- a/constraint/pkg/client/drivers/local/local_unit_test.go +++ b/constraint/pkg/client/drivers/local/local_unit_test.go @@ -114,8 +114,6 @@ func TestDriver_PutModule(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - d := New(Modules(tc.beforeModules)) dr, ok := d.(*driver) @@ -124,7 +122,7 @@ func TestDriver_PutModule(t *testing.T) { d, &driver{}) } - gotErr := d.PutModule(ctx, tc.moduleName, tc.moduleSrc) + gotErr := d.PutModule(tc.moduleName, tc.moduleSrc) if !errors.Is(gotErr, tc.wantErr) { t.Fatalf("got PutModule() error = %v, want %v", gotErr, tc.wantErr) } @@ -243,12 +241,10 @@ func TestDriver_PutModules(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - d := New() for prefix, src := range tc.beforeModules { - err := d.PutModules(ctx, prefix, src) + err := d.PutModules(prefix, src) if err != nil { t.Fatal(err) } @@ -260,7 +256,7 @@ func TestDriver_PutModules(t *testing.T) { d, &driver{}) } - gotErr := d.PutModules(ctx, tc.prefix, tc.srcs) + gotErr := d.PutModules(tc.prefix, tc.srcs) if !errors.Is(gotErr, tc.wantErr) { t.Fatalf("got PutModules() error = %v, want %v", gotErr, tc.wantErr) } @@ -309,11 +305,9 @@ func TestDriver_PutModules_StorageErrors(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - d := New(Storage(tc.storage)) - err := d.PutModule(ctx, "foo", Module) + err := d.PutModule("foo", Module) if tc.wantErr && err == nil { t.Fatalf("got PutModule() err %v, want error", nil) @@ -383,12 +377,10 @@ func TestDriver_DeleteModule(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - d := New() for _, name := range tc.beforeModules { - err := d.PutModule(ctx, name, Module) + err := d.PutModule(name, Module) if err != nil { t.Fatal(err) } @@ -400,7 +392,7 @@ func TestDriver_DeleteModule(t *testing.T) { d, &driver{}) } - gotDeleted, gotErr := d.DeleteModule(ctx, tc.moduleName) + gotDeleted, gotErr := d.DeleteModule(tc.moduleName) if gotDeleted != tc.wantDeleted { t.Errorf("got DeleteModule() = %t, want %t", gotDeleted, tc.wantDeleted) } @@ -443,16 +435,14 @@ func TestDriver_DeleteModule_StorageErrors(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - d := New(Storage(tc.storage)) - err := d.PutModule(ctx, "foo", Module) + err := d.PutModule("foo", Module) if err != nil { t.Fatal(err) } - _, err = d.DeleteModule(ctx, "foo") + _, err = d.DeleteModule("foo") if tc.wantErr && err == nil { t.Fatalf("got DeleteModule() err %v, want error", nil) @@ -543,8 +533,6 @@ func TestDriver_DeleteModules(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - d := New() for prefix, count := range tc.beforeModules { @@ -552,7 +540,7 @@ func TestDriver_DeleteModules(t *testing.T) { for i := 0; i < count; i++ { modules[i] = Module } - err := d.PutModules(ctx, prefix, modules) + err := d.PutModules(prefix, modules) if err != nil { t.Fatal(err) } @@ -564,7 +552,7 @@ func TestDriver_DeleteModules(t *testing.T) { d, &driver{}) } - gotDeleted, gotErr := d.DeleteModules(ctx, tc.prefix) + gotDeleted, gotErr := d.DeleteModules(tc.prefix) if gotDeleted != tc.wantDeleted { t.Errorf("got DeleteModules() = %v, want %v", gotDeleted, tc.wantDeleted) } diff --git a/constraint/pkg/client/drivers/remote/remote.go b/constraint/pkg/client/drivers/remote/remote.go index 9d14b8263..ed382c5b1 100644 --- a/constraint/pkg/client/drivers/remote/remote.go +++ b/constraint/pkg/client/drivers/remote/remote.go @@ -64,7 +64,7 @@ type driver struct { traceEnabled bool } -func (d *driver) Init(ctx context.Context) error { +func (d *driver) Init() error { return nil } @@ -72,18 +72,18 @@ func (d *driver) addTrace(path string) string { return path + "?explain=full&pretty=true" } -func (d *driver) PutModule(ctx context.Context, name string, src string) error { +func (d *driver) PutModule(name string, src string) error { return d.opa.InsertPolicy(name, []byte(src)) } // PutModules implements drivers.Driver. -func (d *driver) PutModules(ctx context.Context, namePrefix string, srcs []string) error { +func (d *driver) PutModules(namePrefix string, srcs []string) error { panic("not implemented") } // DeleteModule deletes a rule from OPA and returns true if a rule was found and deleted, false // if a rule was not found, and any errors. -func (d *driver) DeleteModule(ctx context.Context, name string) (bool, error) { +func (d *driver) DeleteModule(name string) (bool, error) { err := d.opa.DeletePolicy(name) if err != nil { e := &Error{} @@ -97,17 +97,17 @@ func (d *driver) DeleteModule(ctx context.Context, name string) (bool, error) { } // DeleteModules implements drivers.Driver. -func (d *driver) DeleteModules(ctx context.Context, namePrefix string) (int, error) { +func (d *driver) DeleteModules(namePrefix string) (int, error) { panic("not implemented") } -func (d *driver) PutData(ctx context.Context, path string, data interface{}) error { +func (d *driver) PutData(_ context.Context, path string, data interface{}) error { return d.opa.PutData(path, data) } // DeleteData deletes data from OPA and returns true if data was found and deleted, false // if data was not found, and any errors. -func (d *driver) DeleteData(ctx context.Context, path string) (bool, error) { +func (d *driver) DeleteData(_ context.Context, path string) (bool, error) { err := d.opa.DeleteData(path) if err != nil { e := &Error{} @@ -165,7 +165,7 @@ func makeURLPath(path string) (string, error) { return strings.Join(pieces, "/"), nil } -func (d *driver) Query(ctx context.Context, path string, input interface{}, opts ...drivers.QueryOpt) (*ctypes.Response, error) { +func (d *driver) Query(_ context.Context, path string, input interface{}, opts ...drivers.QueryOpt) (*ctypes.Response, error) { cfg := &drivers.QueryCfg{} for _, opt := range opts { opt(cfg) @@ -213,7 +213,7 @@ func (d *driver) Query(ctx context.Context, path string, input interface{}, opts return resp, nil } -func (d *driver) Dump(ctx context.Context) (string, error) { +func (d *driver) Dump(_ context.Context) (string, error) { response, err := d.opa.Query("", nil) if err != nil { return "", err diff --git a/constraint/pkg/client/e2e_test.go b/constraint/pkg/client/e2e_test.go index d206bebb1..3aacc1891 100644 --- a/constraint/pkg/client/e2e_test.go +++ b/constraint/pkg/client/e2e_test.go @@ -106,26 +106,24 @@ var denyAllCases = []struct { libs: []string{denyTemplateWithLibLib}, }} -func newTestClient(ctx context.Context) (*Client, error) { +func newTestClient() (*Client, error) { d := local.New() b, err := NewBackend(Driver(d)) if err != nil { return nil, err } - return b.NewClient(ctx, Targets(&handler{})) + return b.NewClient(Targets(&handler{})) } func TestE2EAddTemplate(t *testing.T) { for _, tc := range denyAllCases { t.Run(tc.name, func(t *testing.T) { - ctx := context.Background() - - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatal(err) } @@ -138,12 +136,12 @@ func TestE2EDenyAll(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -176,12 +174,12 @@ func TestE2EAudit(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -219,12 +217,12 @@ func TestE2EAuditX2(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -277,12 +275,12 @@ func TestE2EAutoreject(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", denyTemplateRego)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", denyTemplateRego)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -353,12 +351,12 @@ func TestE2ERemoveConstraint(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", denyTemplateRego)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", denyTemplateRego)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -412,13 +410,13 @@ func TestE2ERemoveTemplate(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } tmpl := newConstraintTemplate("Foo", denyTemplateRego) - _, err = c.AddTemplate(ctx, tmpl) + _, err = c.AddTemplate(tmpl) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -470,12 +468,12 @@ func TestE2ETracingOff(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", denyTemplateRego)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", denyTemplateRego)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -505,12 +503,12 @@ func TestE2ETracingOn(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -540,12 +538,12 @@ func TestE2EAuditTracingOn(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -583,12 +581,12 @@ func TestE2EAuditTracingOff(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", tc.rego, tc.libs...)) + _, err = c.AddTemplate(newConstraintTemplate("Foo", tc.rego, tc.libs...)) if err != nil { t.Fatalf("got AddTemplate: %v", err) } @@ -626,12 +624,12 @@ func TestE2EDryrunAll(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", `package foo + _, err = c.AddTemplate(newConstraintTemplate("Foo", `package foo violation[{"msg": "DRYRUN", "details": {}}] { "always" == "always" }`)) @@ -668,12 +666,12 @@ func TestE2EDenyByParameter(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - c, err := newTestClient(ctx) + c, err := newTestClient() if err != nil { t.Fatal(err) } - _, err = c.AddTemplate(ctx, newConstraintTemplate("Foo", `package foo + _, err = c.AddTemplate(newConstraintTemplate("Foo", `package foo violation[{"msg": "DENIED", "details": {}}] { input.parameters.name == input.review.Name }`))