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.