Module: Inspec::Schema::Primitives

Defined in:
lib/inspec/schema/primitives.rb

Defined Under Namespace

Classes: SchemaType

Constant Summary collapse

OBJECT =

Establish basic type shorthands for this schema ######################################## These three are essentially primitives, used as shorthand

{ "type" => "object", "additionalProperties" => true }.freeze
NUMBER =
{ "type" => "number" }.freeze
STRING =
{ "type" => "string" }.freeze
NULL =
{ "type" => "null" }.freeze
URL =

We might eventually enforce string format stuff on this

{ "type" => "string" }.freeze
TAGS =

A controls tags can have any number of properties, and any sorts of values

{ "type" => "object", "additionalProperties" => true }.freeze
INPUT =

Attributes/Inputs specify the inputs to a profile.

{ "type" => "object", "additionalProperties" => true }.freeze
IMPACT =

Within a control file, impacts can be numeric 0-1 or string in [none,low,medium,high,critical] However, when they are output, the string types are automatically converted as follows: none -> 0 to 0.01 low -> 0.01 to 0.4 medium -> 0.4 to 0.7 high -> 0.7 to 0.9 Critical -> 0.9 to 1.0 (inclusive)

{
  "type" => "number",
  "minimum" => 0.0,
  "maximum" => 1.0,
}.freeze
STATUS =

A status for a control

{
  "type" => "string",
  "enum" => %w{passed failed skipped error},
}.freeze
STATISTIC_ITEM =

We use “title” to name the type. and “description” (via the describe function) to describe its particular usage Summary item containing run statistics about a subset of the controls

SchemaType.new("Statistic Block", {
  "type" => "object",
  "additionalProperties" => true,
  "required" => ["total"],
  "properties" => {
    "total" => desc(NUMBER, "Total number of controls (in this category) for this inspec execution."),
  },
}, [])
STATISTIC_GROUPING =

Bundles several results statistics, representing distinct groups of controls

SchemaType.new("Statistic Hash", {
  "type" => "object",
  "additionalProperties" => true,
  "required" => [],
  "properties" => {
      "passed" => STATISTIC_ITEM.ref,
      "skipped" => STATISTIC_ITEM.ref,
      "failed" => STATISTIC_ITEM.ref,
  },
}, [STATISTIC_ITEM])
STATISTICS =

Contains statistics of an exec run.

SchemaType.new("Statistics", {
  "type" => "object",
  "additionalProperties" => true,
  "required" => ["duration"],
  "properties" => {
    "duration" => desc(NUMBER, "How long (in seconds) this inspec exec ran for."),
    "controls" => desc(STATISTIC_GROUPING.ref, "Breakdowns of control statistics by result"),
  },
}, [STATISTIC_GROUPING])
DEPENDENCY =

Profile dependencies

SchemaType.new("Dependency", {
  "type" => "object",
  "additionalProperties" => true, # Weird stuff shows up here sometimes
  "required" => [], # Mysteriously even in a run profile we can have no status
  "properties" => {
    "name" => STRING,
    "url" => URL,
    "branch" => STRING,
    "path" => STRING,
    "status_message" => STRING,
    "status" => STRING,
    "git" => URL,
    "supermarket" => STRING,
    "compliance" => STRING,
  },
}, [])
PLATFORM =

Represents the platform the test was run on

SchemaType.new("Platform", {
  "type" => "object",
  "additionalProperties" => true,
  "required" => %w{name release},
  "properties" => {
    "name" => desc(STRING, "The name of the platform this was run on."),
    "release" => desc(STRING, "The version of the platform this was run on."),
    "target_id" => STRING,
  },
}, [])
GENERATOR =

Explains what software ran the inspec profile/made this file. Typically inspec but could in theory be a different software

SchemaType.new("Generator", {
  "type" => "object",
  "additionalProperties" => true,
  "required" => %w{name version},
  "properties" => {
    "name" => desc(STRING, "The name of the software that generated this report."),
    "version" => desc(STRING, "The version of the software that generated this report."),
  },
}, [])
SOURCE_LOCATION =

Occurs from “exec –reporter json” and “inspec json” Denotes what file this control comes from, and where within

SchemaType.new("Source Location", {
  "type" => "object",
  "additionalProperties" => true,
  "properties" => {
    "ref" => desc(STRING, "Path to the file that this statement originates from"),
    "line" => desc(NUMBER, "The line at which this statement is located in the file"),
  },
  "required" => %w{ref line},
}, [])
REFERENCE =

References an external document

SchemaType.new("Reference", {
  # Needs at least one of title (ref), url, or uri.
  "anyOf" => [
    {
      "type" => "object",
      "required" => ["ref"],
      "properties" => { "ref" => STRING },
    },
    {
      "type" => "object",
      "required" => ["url"],
      "properties" => { "url" => STRING },
    },
    {
      "type" => "object",
      "required" => ["uri"],
      "properties" => { "uri" => STRING },
    },
    # I am of the opinion that this is just an error in the codebase itself. See profiles/wrapper-override to uncover new mysteries!
    {
      "type" => "object",
      "required" => ["ref"],
      "properties" => { "ref" => array(OBJECT) },

    },
  ],
}, [])
CONTROL_GROUP =

Represents a group of controls within a profile/.rb file

SchemaType.new("Control Group", {
  "type" => "object",
  "additionalProperties" => true,
  "required" => %w{id controls},
  "properties" => {
    "id" => desc(STRING, "The unique identifier of the group"),
    "title" => desc({ type: %w{string null} }, "The name of the group"),
    "controls" => desc(array(STRING), "The control IDs in this group"),
  },
}, [])
SUPPORT =

Occurs from “inspec exec –reporter json” and “inspec json” Represents a platfrom or group of platforms that this profile supports

SchemaType.new("Supported Platform", {
  "type" => "object",
  "additionalProperties" => true, # NOTE: This should really be false, and inspec should validate profiles to ensure people don't make dumb mistakes like platform_family
  "required" => [],
  "properties" => {
    "platform-family" => STRING,
    "platform-name" => STRING,
    "platform" => STRING,
    "release" => STRING,
    # os-* supports are being deprecated
    "os-family" => STRING,
    "os-name" => STRING,
  },
}, [])

Class Method Summary collapse

Class Method Details

.array(of_type) ⇒ Object

Use this function to easily make an array of a type



15
16
17
18
19
20
# File 'lib/inspec/schema/primitives.rb', line 15

def self.array(of_type)
  {
    "type" => "array",
    "items" => of_type,
  }
end

.desc(obj, description) ⇒ Object

Establish simple helpers for this schema ######################################## Use this function to easily make described types



10
11
12
# File 'lib/inspec/schema/primitives.rb', line 10

def self.desc(obj, description)
  obj.merge({ "description" => description })
end

.validate_schema(schema) ⇒ Object

This function performs some simple validation on schemas, to catch obvious missed requirements



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/inspec/schema/primitives.rb', line 23

def self.validate_schema(schema)
  return if schema["type"] != "object"
  raise "Objects in schema must have a \"required\" property, even if it is empty." unless schema.key?("required")

  return if schema["required"].empty?
  raise "An object with required properties must have a properties hash." unless schema.key?("properties")

  return if Set.new(schema["required"]) <= Set.new(schema["properties"].keys)

  raise "Not all required properties are present."
end