Documentation
¶
Index ¶
- Constants
- Variables
- func ReadK8sResources(r io.Reader) ([]*unstructured.Unstructured, error)
- func ReadObject(f fs.FS, path string) (*unstructured.Unstructured, error)
- func ReadTemplate(scheme *runtime.Scheme, f fs.FS, path string) (*templates.ConstraintTemplate, error)
- func ToTemplate(scheme *runtime.Scheme, u *unstructured.Unstructured) (*templates.ConstraintTemplate, error)
- type Assertion
- type Case
- type CaseResult
- type Client
- type Duration
- type Filter
- type Printer
- type PrinterGo
- func (p PrinterGo) Print(w StringWriter, r []SuiteResult, verbose bool) error
- func (p PrinterGo) PrintCase(w StringWriter, r *CaseResult, verbose bool) error
- func (p PrinterGo) PrintSuite(w StringWriter, r *SuiteResult, verbose bool) error
- func (p PrinterGo) PrintTest(w StringWriter, r *TestResult, verbose bool) error
- type Runner
- type StringWriter
- type Suite
- type SuiteResult
- type Test
- type TestResult
Constants ¶
const ( // Group is the API Group for Test YAML objects. Group = "test.gatekeeper.sh" // Kind is the Kind for Suite YAML objects. Kind = "Suite" )
Variables ¶
var ( // ErrNotATemplate indicates the user-indicated file does not contain a // ConstraintTemplate. ErrNotATemplate = errors.New("not a ConstraintTemplate") // ErrNotAConstraint indicates the user-indicated file does not contain a // Constraint. ErrNotAConstraint = errors.New("not a Constraint") // ErrAddingTemplate indicates a problem instantiating a Suite's ConstraintTemplate. ErrAddingTemplate = errors.New("adding template") // ErrAddingConstraint indicates a problem instantiating a Suite's Constraint. ErrAddingConstraint = errors.New("adding constraint") // ErrInvalidSuite indicates a Suite does not define the required fields. ErrInvalidSuite = errors.New("invalid Suite") // ErrCreatingClient indicates an error instantiating the Client which compiles // Constraints and runs validation. ErrCreatingClient = errors.New("creating client") // ErrInvalidCase indicates a Case cannot be run due to not being configured properly. ErrInvalidCase = errors.New("invalid Case") // ErrNumViolations indicates an Object did not get the expected number of // violations. ErrNumViolations = errors.New("unexpected number of violations") // ErrInvalidRegex indicates a Case specified a Violation regex that could not // be compiled. ErrInvalidRegex = errors.New("message contains invalid regular expression") // ErrInvalidFilter indicates that Filter construction failed. ErrInvalidFilter = errors.New("invalid test filter") // ErrNoObjects indicates that a specified YAML file contained no objects. ErrNoObjects = errors.New("missing objects") // ErrMultipleObjects indicates that a specified YAML file contained multiple objects. ErrMultipleObjects = errors.New("object file must contain exactly one object") // ErrAddInventory indicates that an object that was declared to be part of // data.inventory was unable to be added. ErrAddInventory = errors.New("unable to add object to data.inventory") // ErrConvertingTemplate means we were able to parse a template, but not convert // it into the version-independent format. ErrConvertingTemplate = errors.New("unable to convert template") )
var ( // ErrNoFileSystem means a method which expects a filesystem got nil // instead. This is likely a bug in the code. ErrNoFileSystem = errors.New("no filesystem") // ErrNoTarget indicates that the user did not specify a target directory or // file. ErrNoTarget = errors.New("target not specified") // ErrUnsupportedExtension indicates that a user attempted to run tests in // a file type which is not supported. ErrUnsupportedExtension = errors.New("unsupported extension") // ErrInvalidYAML indicates that a .yaml/.yml file was not parseable. ErrInvalidYAML = errors.New("invalid yaml") // ErrNotADirectory indicates that a user is mistakenly attempting to // perform a directory-only action on a file (for example, recursively // traversing it). ErrNotADirectory = errors.New("not a directory") )
var ErrWritingString = errors.New("writing output")
ErrWritingString means there was a problem writing output to the writer passed to Print.
Functions ¶
func ReadK8sResources ¶
func ReadK8sResources(r io.Reader) ([]*unstructured.Unstructured, error)
ReadK8sResources reads JSON or YAML k8s resources from an io.Reader, decoding them into Unstructured objects and returning those objects as a slice.
func ReadObject ¶
func ReadObject(f fs.FS, path string) (*unstructured.Unstructured, error)
ReadObject reads a file from the filesystem abstraction at the specified path, and returns an unstructured.Unstructured object if the file can be successfully unmarshalled.
func ReadTemplate ¶
func ReadTemplate(scheme *runtime.Scheme, f fs.FS, path string) (*templates.ConstraintTemplate, error)
ReadTemplate reads the contents of the path and returns the ConstraintTemplate it defines. Returns an error if the file does not define a ConstraintTemplate.
func ToTemplate ¶
func ToTemplate(scheme *runtime.Scheme, u *unstructured.Unstructured) (*templates.ConstraintTemplate, error)
ToTemplate converts an unstructured template into a versionless ConstraintTemplate struct.
Types ¶
type Assertion ¶
type Assertion struct {
// Violations, if set, indicates either whether there are violations, or how
// many violations match this assertion.
//
// The value may be either an integer, of a string. If an integer, exactly
// this number of violations must otherwise match this Assertion. If a string,
// must be either "yes" or "no". If "yes" at least one violation must match
// the Assertion to be satisfied. If "no", there must be zero violations
// matching the Assertion to be satisfied.
//
// Defaults to "yes".
Violations *intstr.IntOrString `json:"violations,omitempty"`
// Message is a regular expression which matches the Msg field of individual
// violations.
//
// If unset, has no effect and all violations match this Assertion.
Message *string `json:"message,omitempty"`
// contains filtered or unexported fields
}
An Assertion is a declaration about the data returned by running an object against a Constraint.
type Case ¶
type Case struct {
Name string `json:"name"`
// Object is the path to the file containing a Kubernetes object to test.
Object string `json:"object"`
// Inventory is a list of paths to files containing Kubernetes objects to put
// in data.inventory for testing referential constraints.
Inventory []string `json:"inventory"`
// Assertions are statements which must be true about the result of running
// Review with the Test's Constraint on the Case's Object.
//
// All Assertions must succeed in order for the test to pass.
// If no assertions are present, assumes reviewing Object produces no
// violations.
Assertions []Assertion `json:"assertions"`
// Skip, if true, skips this Case.
Skip bool `json:"skip"`
}
Case runs Constraint against a YAML object.
type CaseResult ¶
type CaseResult struct {
// Name is the name given to this test for the Constraint under test.
Name string
// Skipped is whether this Case was skipped while running its parent Test.
Skipped bool
// Error is the either:
// 1) why this case failed, or
// 2) the error which prevented running this case.
// We don't need to distinguish between 1 and 2 - they are both treated as
// failures.
Error error
// Runtime is the time it took for this Case to run.
Runtime Duration
}
CaseResult is the result of evaluating a Constraint against a kubernetes object, and comparing the result with the expected result.
func (*CaseResult) IsFailure ¶
func (r *CaseResult) IsFailure() bool
IsFailure returns true if the test failed to execute or produced an unexpected result.
type Client ¶
type Client interface {
// AddTemplate adds a Template to the Client. Templates define the structure
// and parameters of potential Constraints.
AddTemplate(ctx context.Context, templ *templates.ConstraintTemplate) (*types.Responses, error)
// AddConstraint adds a Constraint to the Client. Must map to one of the
// previously-added Templates.
//
// Returns an error if the referenced Template does not exist, or the
// Constraint does not match the structure defined by the referenced Template.
AddConstraint(ctx context.Context, constraint *unstructured.Unstructured) (*types.Responses, error)
// AddData adds the state of the cluster. For use in referential Constraints.
AddData(ctx context.Context, data interface{}) (*types.Responses, error)
// RemoveData removes objects from the state of the cluster. For use in
// referential constraints.
RemoveData(ctx context.Context, data interface{}) (*types.Responses, error)
// Review runs all Constraints against obj.
Review(ctx context.Context, obj interface{}, opts ...drivers.QueryOpt) (*types.Responses, error)
}
func NewOPAClient ¶
type Duration ¶
Duration is an alias of time.Duration to allow for custom formatting. Otherwise time formatting must be done inline everywhere.
type Filter ¶
type Filter interface {
// MatchesTest returns true if the Test should be run.
MatchesTest(Test) bool
// MatchesCase returns true if Case caseName in Test testName should be run.
MatchesCase(testName, caseName string) bool
}
func NewFilter ¶
NewFilter parses run into a Filter for selecting constraint tests and individual cases to run.
Empty string results in a Filter which matches all tests and their cases.
Examples: 1) NewFiler("require-foo-label//missing-label") Matches tests containing the string "require-foo-label" and cases containing the string "missing-label". So this would match all of the following: - Test: "require-foo-label", Case: "missing-label" - Test: "not-require-foo-label, Case: "not-missing-label" - Test: "require-foo-label", Case: "missing-label-and-annotation"
2) NewFilter("missing-label") Matches cases which either have a name containing "missing-label" or which are in a test named "missing-label". Matches the following: - Test: "forbid-missing-label", Case: "with-foo-label" - Test: "required-labels", Case: "missing-label"
3) NewFilter("^require-foo-label$//") Matches tests which exactly match "require-foo-label". Matches the following: - Test: "require-foo-label", Case: "with-foo-label" - Test: "require-foo-label", Case: "no-labels"
4) NewFilter("//empty-object") Matches tests whose names contain the string "empty-object". Matches the following: - Test: "forbid-foo-label", Case: "empty-object" - Test: "forbid-foo-label", Case: "another-empty-object" - Test: "require-bar-annotation", Case: "empty-object".
type Printer ¶
type Printer interface {
// Print formats and writes SuiteResult to w. If verbose it true, prints more
// extensive output (behavior is specific to the printer). Returns an error
// if there is a problem writing to w.
Print(w StringWriter, r []SuiteResult, verbose bool) error
}
Printer knows how to print the results of running a Suite.
type PrinterGo ¶
type PrinterGo struct{}
func (PrinterGo) Print ¶
func (p PrinterGo) Print(w StringWriter, r []SuiteResult, verbose bool) error
func (PrinterGo) PrintCase ¶
func (p PrinterGo) PrintCase(w StringWriter, r *CaseResult, verbose bool) error
func (PrinterGo) PrintSuite ¶
func (p PrinterGo) PrintSuite(w StringWriter, r *SuiteResult, verbose bool) error
func (PrinterGo) PrintTest ¶
func (p PrinterGo) PrintTest(w StringWriter, r *TestResult, verbose bool) error
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner defines logic independent of how tests are run and the results are printed.
type StringWriter ¶
StringWriter knows how to write a string to a Writer.
Note: StringBuffer meets this interface.
type Suite ¶
type Suite struct {
metav1.ObjectMeta
// Tests is a list of Template&Constraint pairs, with tests to run on
// each.
Tests []Test `json:"tests"`
// Path is the filepath of this Suite on disk.
Path string `json:"-"`
// Skip, if true, skips this Suite.
Skip bool `json:"skip"`
}
Suite defines a set of Constraint tests.
func ReadSuites ¶
ReadSuites returns the set of test Suites selected by path.
- If path is a path to a Suite, parses and returns the Suite.
- If the path is a directory and recursive is false, returns only the Suites defined in that directory.
- If the path is a directory and recursive is true returns all Suites in that directory and its subdirectories.
Returns an error if: - path is a file that does not define a Suite - any matched files containing Suites are not parseable.
type SuiteResult ¶
type SuiteResult struct {
// Path is the absolute path to the file which defines Suite.
Path string
// Error is the error which stopped the Suite from executing.
// If defined, TestResults is empty.
Error error
// Runtime is the time it took for this Suite of tests to run.
Runtime Duration
// TestResults are the results of running the tests for each defined
// Template/Constraint pair.
TestResults []TestResult
// Skipped is whether this Suite was skipped and not run.
Skipped bool
}
SuiteResult is the Result of running a Suite of tests.
func (*SuiteResult) IsFailure ¶
func (r *SuiteResult) IsFailure() bool
IsFailure returns true if there was a problem running the Suite, or one of the Constraint tests failed.
type Test ¶
type Test struct {
Name string `json:"name"`
// Template is the path to the ConstraintTemplate, relative to the file
// defining the Suite.
Template string `json:"template"`
// Constraint is the path to the Constraint, relative to the file defining
// the Suite. Must be an instance of Template.
Constraint string `json:"constraint"`
// Cases are the test cases to run on the instantiated Constraint.
Cases []*Case `json:"cases,omitempty"`
// Skip, if true, skips this Test.
Skip bool `json:"skip"`
}
Test defines a Template&Constraint pair to instantiate, and Cases to run on the instantiated Constraint.
type TestResult ¶
type TestResult struct {
// Name is the name given to the Template/Constraint pair under test.
Name string
// Skipped is whether this Test was skipped while running its parent Suite.
Skipped bool
// Error is the error which prevented running tests for this Constraint.
// If defined, CaseResults is empty.
Error error
// Runtime is the time it took for the Template/Constraint to be compiled, and
// the test Cases to run.
Runtime Duration
// CaseResults are individual results for all tests defined for this Constraint.
CaseResults []CaseResult
}
TestResult is the results of: 1) Compiling the ConstraintTemplate, 2) Instantiating the Constraint, and 3) Running all Tests defined for the Constraint.
func (*TestResult) IsFailure ¶
func (r *TestResult) IsFailure() bool
IsFailure returns true if there was a problem running the Constraint tests, or one of its Tests failed.