{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "#/definitions/Patch",
  "$id": "https://ela.st/harp-v1-patch.json",
  "definitions": {
    "Patch": {
      "properties": {
        "apiVersion": {
          "type": "string",
          "description": "Default to \"harp.elastic.co/v1\"",
          "const": "harp.elastic.co/v1"
        },
        "kind": {
          "type": "string",
          "description": "Default to \"BundlePatch\"",
          "const": "BundlePatch"
        },
        "meta": {
          "$ref": "#/definitions/harp.bundle.v1.PatchMeta",
          "additionalProperties": false,
          "description": "BundlePatch metadata"
        },
        "spec": {
          "$ref": "#/definitions/harp.bundle.v1.PatchSpec",
          "additionalProperties": false,
          "description": "BundlePatch specification"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch",
      "description": "Patch represents bundle patch definition."
    },
    "harp.bundle.v1.PatchExecutor": {
      "properties": {
        "disableAnnotations": {
          "type": "boolean",
          "description": "Enable/Disable annotations after patch application.",
          "default": false
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Executor"
    },
    "harp.bundle.v1.PatchMeta": {
      "properties": {
        "name": {
          "type": "string",
          "description": "Patch name.",
          "default": "bundle-patch-1",
          "examples": [
            "postgresql-rotator",
            "ssh-provisioner",
            "add-cluster-user"
          ]

        },
        "owner": {
          "type": "string",
          "description": "Patch owner.",
          "default": "owner@domain.tld"
        },
        "description": {
          "type": "string",
          "description": "Short description for template role.",
          "default": "This patch is used for ..."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Meta",
      "description": "PatchMeta handles patch metadata."
    },
    "harp.bundle.v1.PatchOperation": {
      "properties": {
        "add": {
          "additionalProperties": {
            "type": "string"
          },
          "type": ["object", "null"],
          "description": "Add a new case-sentitive key and value to related data map. Key and Value can be templatized.",
          "default": {
            "key": "value"
          }
        },
        "remove": {
          "items": {
            "type": "string"
          },
          "type": ["array", "null"],
          "description": "Remove a case-sensitive key from related data map. Key and Value can be templatized.",
          "default": ["key"]
        },
        "update": {
          "additionalProperties": {
            "type": "string"
          },
          "type": ["object", "null"],
          "description": "Update case-sensitive existing key from related data map. Key and Value can be templatized.",
          "default": {
            "key-1": "new-value"
          }
        },
        "replaceKeys": {
          "additionalProperties": {
            "type": "string"
          },
          "type": ["object", "null"],
          "description": "Replace case-sensitive existing key using the associated value. Value can be templatized.",
          "default": {
            "key-1": "new-key-1"
          }
        },
        "removeKeys": {
          "items": {
            "type": "string"
          },
          "type": ["array", "null"],
          "description": "Remove all keys matching these given regexp.",
          "default": ["key-to-remove-1", "key-to-remove-2"]
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Operation",
      "description": "PatchOperation represents atomic patch operations executable on a k/v map."
    },
    "harp.bundle.v1.PatchPackage": {
      "properties": {
        "path": {
          "$ref": "#/definitions/harp.bundle.v1.PatchPackagePath",
          "additionalProperties": false,
          "description": "Path operations."
        },
        "annotations": {
          "$ref": "#/definitions/harp.bundle.v1.PatchOperation",
          "additionalProperties": false,
          "description": "Annotation operations."
        },
        "labels": {
          "$ref": "#/definitions/harp.bundle.v1.PatchOperation",
          "additionalProperties": false,
          "description": "Label operations."
        },
        "data": {
          "$ref": "#/definitions/harp.bundle.v1.PatchSecret",
          "additionalProperties": false,
          "description": "Secret data operations."
        },
        "remove": {
          "type": "boolean",
          "description": "Flag as remove."
        },
        "create": {
          "type": "boolean",
          "description": "Flag to create if not exist."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Package",
      "description": "PatchPackage represents package operations."
    },
    "harp.bundle.v1.PatchPackagePath": {
      "properties": {
        "template": {
          "type": "string",
          "title": "Path replacement template",
          "description": "Template used to completely rewrite the package path.\n Use `{{.Path}}` to retrieve current path value.",
          "default": "{{.Path}}",
          "examples": [
            "{{ trimPrefix \"secrets/\" .Path }}"
          ]
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Package Path",
      "description": "PatchPackagePath represents package path operations."
    },
    "harp.bundle.v1.PatchRule": {
      "properties": {
        "id": {
          "type": ["string", "null"],
          "description": "Rule identifier."
        },
        "selector": {
          "$ref": "#/definitions/harp.bundle.v1.PatchSelector",
          "additionalProperties": false,
          "description": "Used to determine is patch strategy is applicable to the package."
        },
        "package": {
          "$ref": "#/definitions/harp.bundle.v1.PatchPackage",
          "additionalProperties": false,
          "description": "Package patch operations."
        }
      },
      "required": ["selector", "package"],
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Rule",
      "description": "PatchRule represents an operation to apply to a given bundle."
    },
    "harp.bundle.v1.PatchSecret": {
      "properties": {
        "annotations": {
          "$ref": "#/definitions/harp.bundle.v1.PatchOperation",
          "additionalProperties": false,
          "description": "Secret data annotation operations."
        },
        "labels": {
          "$ref": "#/definitions/harp.bundle.v1.PatchOperation",
          "additionalProperties": false,
          "description": "Secret data label operations."
        },
        "template": {
          "type": ["string", "null"],
          "description": "Template to override secret data."
        },
        "kv": {
          "$ref": "#/definitions/harp.bundle.v1.PatchOperation",
          "additionalProperties": false,
          "description": "Used to target specific keys inside the secret data."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Secret",
      "description": "PatchSecret represents secret data operations."
    },
    "harp.bundle.v1.PatchSelector": {
      "properties": {
        "matchPath": {
          "$ref": "#/definitions/harp.bundle.v1.PatchSelectorMatchPath",
          "additionalProperties": false,
          "description": "Match a package by using its path (secret path)."
        },
        "jmesPath": {
          "type": ["string", "null"],
          "description": "Match a package using a JMESPath query."
        },
        "rego": {
          "type": ["string", "null"],
          "description": "Match a package using a Rego policy."
        },
        "regoFile": {
          "type": ["string", "null"],
          "description": "Match a package using a REgo policy stored in an external file."
        },
        "matchSecret": {
          "$ref": "#/definitions/harp.bundle.v1.PatchSelectorMatchSecret",
          "additionalProperties": false,
          "description": "Match a package by secret."
        },
        "cel": {
          "items": {
            "type": "string"
          },
          "type": ["array", "null"],
          "description": "Match a package using CEL expressions."
        }
      },
      "oneOf": [{
          "required": ["matchPath"]
        },
        {
          "required": ["jmesPath"]
        },
        {
          "required": ["rego"]
        },
        {
          "required": ["regoFile"]
        },
        {
          "required": ["matchSecret"]
        },
        {
          "required": ["cel"]
        }
      ],
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Selector",
      "description": "PatchSelector represents selecting strategies used to match a bundle resource."
    },
    "harp.bundle.v1.PatchSelectorMatchPath": {
      "properties": {
        "strict": {
          "type": "string",
          "description": "Strict case-sensitive path matching. Value can be templatized.",
          "default": "app/secret/path",
          "examples": [
            "app/{{.Values.quality}}/database/admin_account"
          ]
        },
        "regex": {
          "type": "string",
          "description": "Regex path matching. Value can be templatized.",
          "default": "^app/(production|staging)/security/databases/.*_credentials$"
        },
        "glob": {
          "type": "string",
          "description": "Glob path matching. - https://github.com/gobwas/glob Value can be templatized.",
          "default": "infra/aws/**",
          "examples": [
            "infra/aws/{{.Region}}/ec2/ssh_key"
          ]
        }
      },
      "oneOf": [{
          "required": ["strict"]
        },
        {
          "required": ["regex"]
        },
        {
          "required": ["glob"]
        }
      ],
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Selector Match Path",
      "description": "PatchSelectorMatchPath represents package path matching strategies."
    },
    "harp.bundle.v1.PatchSelectorMatchSecret": {
      "properties": {
        "strict": {
          "type": "string",
          "description": "Strict case-sensitive secret matching. Value can be templatized."
        },
        "regex": {
          "type": "string",
          "description": "Regex secret matching. Value can be templatized."
        },
        "glob": {
          "type": "string",
          "description": "Glob path matching. - https://github.com/gobwas/glob Value can be templatized."
        }
      },
      "oneOf": [{
          "required": ["strict"]
        },
        {
          "required": ["regex"]
        },
        {
          "required": ["glob"]
        }
      ],
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Selector Match Secret",
      "description": "PatchSelectorMatchPath represents package path matching strategies."
    },
    "harp.bundle.v1.PatchSpec": {
      "properties": {
        "executor": {
          "$ref": "#/definitions/harp.bundle.v1.PatchExecutor",
          "additionalProperties": false
        },
        "rules": {
          "items": {
            "$ref": "#/definitions/harp.bundle.v1.PatchRule"
          },
          "additionalProperties": false,
          "type": "array",
          "description": "Patch selector rules. Applied in the declaration order."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Patch Spec",
      "description": "PatchSpec repesetns bundle patch specification holder."
    }
  }
}
