{
  "description": "ArtifactGenerator is the Schema for the artifactgenerators API.",
  "properties": {
    "apiVersion": {
      "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
      "type": "string"
    },
    "kind": {
      "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "spec": {
      "description": "ArtifactGeneratorSpec defines the desired state of ArtifactGenerator.",
      "properties": {
        "artifacts": {
          "description": "OutputArtifacts is a list of output artifacts to be generated.",
          "items": {
            "description": "OutputArtifact defines the desired state of an ExternalArtifact\ngenerated by the ArtifactGenerator.",
            "properties": {
              "copy": {
                "description": "Copy defines a list of copy operations to perform from the sources to the generated artifact.\nThe copy operations are performed in the order they are listed with existing files\nbeing overwritten by later copy operations.",
                "items": {
                  "properties": {
                    "exclude": {
                      "description": "Exclude specifies a list of glob patterns to exclude\nfiles and dirs matched by the 'From' field. Patterns are matched\nagainst paths relative to the source alias root or to the non-glob\nprefix of 'From'. Patterns without a separator (e.g. \"*.md\") match\nthe file name at any depth.",
                      "items": {
                        "maxLength": 1024,
                        "type": "string"
                      },
                      "maxItems": 100,
                      "type": "array"
                    },
                    "from": {
                      "description": "From specifies the source (by alias) and the glob pattern to match files.\nThe format is \"@<alias>/<glob-pattern>\". When pathPattern is set,\nthe path may use capture placeholders such as \"{app}\".",
                      "maxLength": 1024,
                      "minLength": 1,
                      "pattern": "^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$",
                      "type": "string"
                    },
                    "optional": {
                      "description": "Optional, when set to true, allows the copy operation to silently\nskip when the source path or glob pattern matches no files.\nWhen false (default), the reconciliation fails with an error if\nno files are matched.",
                      "type": "boolean"
                    },
                    "strategy": {
                      "description": "Strategy specifies the copy strategy to use.\n'Overwrite' will overwrite existing files in the destination.\n'Merge' is for merging YAML files using Helm values merge strategy.\n'Extract' is for extracting the contents of tarball archives (.tar.gz, .tgz)\nWhen using glob patterns, non-tarball files are silently skipped. For single file sources,\nthe file must be a tarball or an error is returned. Directories are not supported.\nIf not specified, defaults to 'Overwrite'.",
                      "enum": [
                        "Overwrite",
                        "Merge",
                        "Extract"
                      ],
                      "type": "string"
                    },
                    "to": {
                      "description": "To specifies the destination path within the artifact.\nThe format is \"@artifact/path\", the alias \"artifact\"\nrefers to the root path of the generated artifact. When pathPattern\nis set, the path may use capture placeholders such as \"{app}\".",
                      "maxLength": 1024,
                      "minLength": 1,
                      "pattern": "^@artifact/([^/]{0,1}|[^./][^/]|[.][^./]|[^/]{3,})(/([^/]{0,1}|[^./][^/]|[.][^./]|[^/]{3,}))*$",
                      "type": "string"
                    }
                  },
                  "required": [
                    "from",
                    "to"
                  ],
                  "type": "object",
                  "additionalProperties": false
                },
                "minItems": 1,
                "type": "array"
              },
              "inputsFrom": {
                "description": "InputsFrom specifies a source path to a YAML file whose contents are\nexported in the ExternalArtifact .status.exportedInputs field.\nThe format is \"@<alias>/<path>\", where <alias> references a source or\n\"artifact\" for the generated artifact itself. When pathPattern is set,\nthe path may use capture placeholders such as \"{module}\".",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$",
                "type": "string"
              },
              "name": {
                "description": "Name is the name of the generated artifact.\nWhen pathPattern is set, this field may use capture placeholders such as \"{app}\".\nThe maximum length accommodates capture placeholders; the effective\nlimits are enforced by the CEL validation when pathPattern is not set.",
                "maxLength": 1024,
                "type": "string"
              },
              "namespace": {
                "description": "Namespace is the namespace of the generated artifact.\nIf not provided, defaults to the same namespace as the ArtifactGenerator.\nWhen pathPattern is set, this field may use capture placeholders such as \"{app}\".\nThe credentials used to reconcile the artifact are described in\n.spec.serviceAccountName: an explicit ServiceAccount applies to every\ngenerated artifact, while the --default-service-account flag only applies\nto artifacts in a namespace other than the ArtifactGenerator namespace.\nThe maximum length accommodates capture placeholders; the effective\nlimits are enforced by the CEL validation when pathPattern is not set.",
                "maxLength": 1024,
                "type": "string"
              },
              "originRevision": {
                "description": "OriginRevision is used to set the 'org.opencontainers.image.revision'\nannotation on the generated artifact metadata.\nIf specified, it must point to an existing source alias in the format \"@<alias>\".\nIf the referenced source has an origin revision (e.g. a Git commit SHA),\nit will be used to set the annotation on the generated artifact.\nIf the referenced source does not have an origin revision, the field is ignored.",
                "maxLength": 64,
                "pattern": "^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)$",
                "type": "string"
              },
              "revision": {
                "description": "Revision is the revision of the generated artifact.\nIf specified, it must point to an existing source alias in the format \"@<alias>\".\nIf not specified, the revision is automatically set to the digest of the artifact content.",
                "maxLength": 64,
                "pattern": "^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)$",
                "type": "string"
              }
            },
            "required": [
              "copy",
              "name"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "maxItems": 1000,
          "minItems": 1,
          "type": "array"
        },
        "commonMetadata": {
          "description": "CommonMetadata specifies the common labels and annotations that are\napplied to all resources. Any existing label or annotation will be\noverridden if its key matches a common one.",
          "properties": {
            "annotations": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Annotations to be added to the object's metadata.",
              "type": "object"
            },
            "labels": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Labels to be added to the object's metadata.",
              "type": "object"
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "managedNamespaces": {
          "description": "ManagedNamespaces defines how the controller manages the namespaces\ntargeted by the generated artifacts. When omitted, the target namespaces\nare unmanaged: they must already exist and are left untouched.",
          "properties": {
            "allowedNames": {
              "description": "AllowedNames is a list of CEL expressions that define the set of\nnamespaces the ArtifactGenerator agrees to manage. Each expression\nreceives the namespace name through the 'ns' string variable and must\nreturn a boolean. A namespace is managed only when at least one\nexpression returns true. The 'default', 'kube-system', 'kube-public'\nand 'flux-system' namespaces are always rejected, regardless of the\nexpressions.",
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "type": "array"
            },
            "metadata": {
              "description": "Metadata defines how the metadata of the desired namespaces is built,\non top of .spec.commonMetadata.",
              "properties": {
                "from": {
                  "description": "From is a list of metadata operations applied in order to the desired\nnamespaces, on top of .spec.commonMetadata and .fromSource.",
                  "items": {
                    "description": "NamespaceMetadataFrom defines a metadata operation applied to a desired\nnamespace.",
                    "properties": {
                      "annotations": {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "description": "Annotations to be applied to the namespace.",
                        "type": "object"
                      },
                      "labels": {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "description": "Labels to be applied to the namespace.",
                        "type": "object"
                      },
                      "namespace": {
                        "description": "Namespace is the name of the desired namespace the metadata applies to,\nor '*' to apply the metadata to all desired namespaces.",
                        "maxLength": 63,
                        "pattern": "^(\\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)$",
                        "type": "string"
                      },
                      "strategy": {
                        "description": "Strategy specifies how the labels and annotations are applied.\n'Reset' clears all the existing labels and annotations before applying\nthe ones defined in the operation (fields that are not set clear the\ncorresponding metadata), 'Override' merges the ones defined in the\noperation into the existing values, overriding existing keys, while\n'Merge' merges only the absent keys, preserving existing values.",
                        "enum": [
                          "Reset",
                          "Override",
                          "Merge"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "namespace",
                      "strategy"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  },
                  "type": "array"
                },
                "fromSource": {
                  "description": "FromSource sources namespace metadata from a NamespaceMetadata file\ninside a source artifact.",
                  "properties": {
                    "allowedAnnotations": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "AllowedAnnotations is a schema for the annotations that the\nNamespaceMetadata file is allowed to set. Each key is an annotation key\nand each value is a CEL expression that receives the annotation value\nthrough the 'value' string variable and must return a boolean.\nAnnotations whose key is not present in this map are ignored, while\nannotations whose value does not satisfy the respective expression are\nrejected.\nThe expressions are compiled, so a malformed expression or one that\ndoes not return a boolean fails validation at the start of the\nreconciliation.",
                      "type": "object"
                    },
                    "allowedLabels": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "AllowedLabels is a schema for the labels that the NamespaceMetadata\nfile is allowed to set. Each key is a label key and each value is a\nCEL expression that receives the label value through the 'value' string\nvariable and must return a boolean. Labels whose key is not present in\nthis map are ignored, while labels whose value does not satisfy the\nrespective expression are rejected.\nThe expressions are compiled, so a malformed expression or one that\ndoes not return a boolean fails validation at the start of the\nreconciliation.",
                      "type": "object"
                    },
                    "path": {
                      "description": "Path is the path to the NamespaceMetadata file inside a source artifact,\nin the format \"@<alias>/<path>\". When pathPattern is set, the path may\nuse capture placeholders such as \"{namespace}\". Only namespace-level\ncaptures are allowed, so that every artifact targeting a namespace\nresolves to the same file.",
                      "maxLength": 1024,
                      "minLength": 1,
                      "pattern": "^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$",
                      "type": "string"
                    }
                  },
                  "required": [
                    "path"
                  ],
                  "type": "object",
                  "x-kubernetes-validations": [
                    {
                      "message": "at least one annotation or label must be set",
                      "rule": "(has(self.allowedAnnotations) && size(self.allowedAnnotations) > 0) || (has(self.allowedLabels) && size(self.allowedLabels) > 0)"
                    }
                  ],
                  "additionalProperties": false
                }
              },
              "type": "object",
              "x-kubernetes-validations": [
                {
                  "message": "either fromSource or at least one from operation must be set",
                  "rule": "has(self.fromSource) || (has(self.from) && size(self.from) > 0)"
                }
              ],
              "additionalProperties": false
            },
            "prune": {
              "description": "Prune specifies whether the controller deletes managed namespaces that\nare no longer targeted by any generated artifact, or when the\nArtifactGenerator is deleted.",
              "type": "boolean"
            }
          },
          "required": [
            "allowedNames",
            "prune"
          ],
          "type": "object",
          "additionalProperties": false
        },
        "pathPattern": {
          "description": "PathPattern specifies a directory traversal pattern to match within the sources.\nThe format is \"@<alias>/<pattern>\". Named captures in the pattern (e.g. \"{app}\")\ncan be used as placeholders in OutputArtifacts fields.",
          "maxLength": 1024,
          "pattern": "^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$",
          "type": "string"
        },
        "serviceAccountName": {
          "description": "ServiceAccountName is the name of the ServiceAccount used to authorize\nthe reconciliation of the generated ExternalArtifacts and the managed\nNamespaces. The name is resolved in the ArtifactGenerator namespace. When\nspecified, the controller checks this ServiceAccount with\nSubjectAccessReview for every namespace targeted by the generated\nExternalArtifacts, including the ArtifactGenerator namespace, and its\nRBAC bindings determine the namespaces in which they can be created,\nupdated and deleted.\nWhen not specified, the controller uses its own credentials for\nExternalArtifacts in the ArtifactGenerator namespace, and the\nServiceAccount configured with the --default-service-account flag\n(when set) for artifacts targeting another namespace.\nNamespace management (.spec.managedNamespaces) always requires a\nServiceAccount for authorization, so either this field or the\n--default-service-account flag must be set; otherwise the reconciliation\nfails with a terminal error. The controller performs the namespace\noperations with its own credentials.",
          "maxLength": 63,
          "minLength": 1,
          "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
          "type": "string"
        },
        "sources": {
          "description": "Sources is a list of references to the Flux source-controller\nresources that will be used to generate the artifact.",
          "items": {
            "description": "SourceReference contains the reference to a Flux source-controller resource.",
            "properties": {
              "alias": {
                "description": "Alias of the source within the ArtifactGenerator context.\nThe alias must be unique per ArtifactGenerator, and must consist\nof lower case alphanumeric characters, underscores, and hyphens.\nIt must start and end with an alphanumeric character.",
                "maxLength": 63,
                "pattern": "^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$",
                "type": "string"
              },
              "kind": {
                "description": "Kind of the source.",
                "enum": [
                  "Bucket",
                  "GitRepository",
                  "OCIRepository",
                  "HelmChart",
                  "ExternalArtifact"
                ],
                "type": "string"
              },
              "name": {
                "description": "Name of the source.",
                "maxLength": 253,
                "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$",
                "type": "string"
              },
              "namespace": {
                "description": "Namespace of the source.\nIf not provided, defaults to the same namespace as the ArtifactGenerator.",
                "maxLength": 63,
                "minLength": 1,
                "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                "type": "string"
              }
            },
            "required": [
              "alias",
              "kind",
              "name"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "maxItems": 1000,
          "minItems": 1,
          "type": "array"
        }
      },
      "required": [
        "artifacts",
        "sources"
      ],
      "type": "object",
      "x-kubernetes-validations": [
        {
          "message": "artifact names must be valid Kubernetes object names when pathPattern is not set",
          "rule": "has(self.pathPattern) && size(self.pathPattern) > 0 || self.artifacts.all(a, a.name.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$') && a.name.size() <= 253)"
        },
        {
          "message": "artifact namespaces must be valid Kubernetes namespaces when pathPattern is not set",
          "rule": "has(self.pathPattern) && size(self.pathPattern) > 0 || self.artifacts.all(a, !has(a.__namespace__) || (a.__namespace__.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$') && a.__namespace__.size() <= 63))"
        }
      ],
      "additionalProperties": false
    },
    "status": {
      "description": "ArtifactGeneratorStatus defines the observed state of ArtifactGenerator.",
      "properties": {
        "conditions": {
          "description": "Conditions holds the conditions for the ArtifactGenerator.",
          "items": {
            "description": "Condition contains details for one aspect of the current state of this API Resource.",
            "properties": {
              "lastTransitionTime": {
                "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
                "maxLength": 32768,
                "type": "string"
              },
              "observedGeneration": {
                "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
                "format": "int64",
                "minimum": 0,
                "type": "integer"
              },
              "reason": {
                "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
                "type": "string"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "enum": [
                  "True",
                  "False",
                  "Unknown"
                ],
                "type": "string"
              },
              "type": {
                "description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
                "maxLength": 316,
                "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        },
        "inventory": {
          "description": "Inventory contains the list of objects managed by the ArtifactGenerator,\nsuch as the generated ExternalArtifacts and the managed Namespaces.",
          "items": {
            "description": "InventoryEntry contains a reference to an object managed by the\nArtifactGenerator, such as a generated ExternalArtifact or a managed\nNamespace.",
            "properties": {
              "digest": {
                "description": "Digest of the referent object. For generated artifacts this is the\nartifact content digest; for managed namespaces this is a digest of the\nmetadata applied by the controller.",
                "type": "string"
              },
              "filename": {
                "description": "Filename is the name of the artifact file.",
                "type": "string"
              },
              "kind": {
                "description": "Kind is the kind of the referent object.",
                "enum": [
                  "ExternalArtifact",
                  "Namespace"
                ],
                "type": "string"
              },
              "name": {
                "description": "Name of the referent object.",
                "type": "string"
              },
              "namespace": {
                "description": "Namespace of the referent object. Empty for cluster-scoped objects.",
                "type": "string"
              }
            },
            "required": [
              "digest",
              "name"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        },
        "lastHandledReconcileAt": {
          "description": "LastHandledReconcileAt holds the value of the most recent\nreconcile request value, so a change of the annotation value\ncan be detected.",
          "type": "string"
        },
        "observedSourcesDigest": {
          "description": "ObservedSourcesDigest is a hash representing the current state of\nall the sources referenced by the ArtifactGenerator.",
          "type": "string"
        }
      },
      "type": "object",
      "additionalProperties": false
    }
  },
  "type": "object"
}
