{
  "description": "AddOnTemplate is the Custom Resource object, it is used to describe\nhow to deploy the addon agent and how to register the addon.\n\nAddOnTemplate is a cluster-scoped resource, and will only be used\non the hub cluster.",
  "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": "spec holds the registration configuration for the addon and the\naddon agent resources yaml description.",
      "properties": {
        "addonName": {
          "description": "AddonName represents the name of the addon which the template belongs to",
          "type": "string"
        },
        "agentSpec": {
          "description": "AgentSpec describes what/how the kubernetes resources of the addon agent to be deployed on a managed cluster.",
          "properties": {
            "deleteOption": {
              "description": "DeleteOption represents deletion strategy when the manifestwork is deleted.\nForeground deletion strategy is applied to all the resource in this manifestwork if it is not set.",
              "properties": {
                "propagationPolicy": {
                  "default": "Foreground",
                  "description": "propagationPolicy can be Foreground, Orphan or SelectivelyOrphan\nSelectivelyOrphan should be rarely used.  It is provided for cases where particular resources is transfering\nownership from one ManifestWork to another or another management unit.\nSetting this value will allow a flow like\n1. create manifestwork/2 to manage foo\n2. update manifestwork/1 to selectively orphan foo\n3. remove foo from manifestwork/1 without impacting continuity because manifestwork/2 adopts it.",
                  "enum": [
                    "Foreground",
                    "Orphan",
                    "SelectivelyOrphan"
                  ],
                  "type": "string"
                },
                "selectivelyOrphans": {
                  "description": "selectivelyOrphan represents a list of resources following orphan deletion stratecy",
                  "properties": {
                    "orphaningRules": {
                      "description": "orphaningRules defines a slice of orphaningrule.\nEach orphaningrule identifies a single resource included in this manifestwork",
                      "items": {
                        "description": "OrphaningRule identifies a single resource included in this manifestwork to be orphaned",
                        "properties": {
                          "group": {
                            "description": "Group is the API Group of the Kubernetes resource,\nempty string indicates it is in core group.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Name is the name of the Kubernetes resource.",
                            "type": "string"
                          },
                          "namespace": {
                            "description": "Name is the namespace of the Kubernetes resource, empty string indicates\nit is a cluster scoped resource.",
                            "type": "string"
                          },
                          "resource": {
                            "description": "Resource is the resource name of the Kubernetes resource.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "name",
                          "resource"
                        ],
                        "type": "object",
                        "additionalProperties": false
                      },
                      "type": "array"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                },
                "ttlSecondsAfterFinished": {
                  "description": "TTLSecondsAfterFinished limits the lifetime of a ManifestWork that has been marked Complete\nby one or more conditionRules set for its manifests. If this field is set, and\nthe manifestwork has completed, then it is elligible to be automatically deleted.\nIf this field is unset, the manifestwork won't be automatically deleted even afer completion.\nIf this field is set to zero, the manfiestwork becomes elligible to be deleted immediately\nafter completion.",
                  "format": "int64",
                  "type": "integer"
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "executor": {
              "description": "Executor is the configuration that makes the work agent to perform some pre-request processing/checking.\ne.g. the executor identity tells the work agent to check the executor has sufficient permission to write\nthe workloads to the local managed cluster.\nNote that nil executor is still supported for backward-compatibility which indicates that the work agent\nwill not perform any additional actions before applying resources.",
              "properties": {
                "subject": {
                  "description": "Subject is the subject identity which the work agent uses to talk to the\nlocal cluster when applying the resources.",
                  "properties": {
                    "serviceAccount": {
                      "description": "ServiceAccount is for identifying which service account to use by the work agent.\nOnly required if the type is \"ServiceAccount\".",
                      "properties": {
                        "name": {
                          "description": "Name is the name of the service account.",
                          "maxLength": 253,
                          "minLength": 1,
                          "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$",
                          "type": "string"
                        },
                        "namespace": {
                          "description": "Namespace is the namespace of the service account.",
                          "maxLength": 253,
                          "minLength": 1,
                          "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "name",
                        "namespace"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": {
                      "description": "Type is the type of the subject identity.\nSupported types are: \"ServiceAccount\".",
                      "enum": [
                        "ServiceAccount"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "type"
                  ],
                  "type": "object",
                  "additionalProperties": false
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "manifestConfigs": {
              "description": "ManifestConfigs represents the configurations of manifests defined in workload field.",
              "items": {
                "description": "ManifestConfigOption represents the configurations of a manifest defined in workload field.",
                "properties": {
                  "conditionRules": {
                    "description": "ConditionRules defines how to set manifestwork conditions for a specific manifest.",
                    "items": {
                      "properties": {
                        "celExpressions": {
                          "description": "CelExpressions defines the CEL expressions to be evaluated for the condition.\nFinal result is the logical AND of all expressions.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "condition": {
                          "description": "Condition is the type of condition that is set based on this rule.\nAny condition is supported, but certain special conditions can be used to\nto control higher level behaviors of the manifestwork.\nIf the condition is Complete, the manifest will no longer be updated once completed.",
                          "type": "string"
                        },
                        "message": {
                          "description": "Message is set on the condition created for this rule",
                          "type": "string"
                        },
                        "messageExpression": {
                          "description": "MessageExpression uses a CEL expression to generate a message for the condition\nWill override message if both are set and messageExpression returns a non-empty string.\nVariables:\n- object: The current instance of the manifest\n- result: Boolean result of the CEL expressions",
                          "type": "string"
                        },
                        "type": {
                          "description": "Type defines how a manifest should be evaluated for a condition.\nIt can be CEL, or WellKnownConditions.\nIf the type is CEL, user should specify the celExpressions field\nIf the type is WellKnownConditions, certain common types in k8s.io/api will be considered\ncompleted as defined by hardcoded rules.",
                          "enum": [
                            "WellKnownConditions",
                            "CEL"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "condition",
                        "type"
                      ],
                      "type": "object",
                      "x-kubernetes-validations": [
                        {
                          "message": "Condition is required for CEL rules",
                          "rule": "self.type != 'CEL' || self.condition != \"\""
                        }
                      ],
                      "additionalProperties": false
                    },
                    "type": "array",
                    "x-kubernetes-list-map-keys": [
                      "condition"
                    ],
                    "x-kubernetes-list-type": "map"
                  },
                  "feedbackRules": {
                    "description": "FeedbackRules defines what resource status field should be returned. If it is not set or empty,\nno feedback rules will be honored.",
                    "items": {
                      "properties": {
                        "jsonPaths": {
                          "description": "JsonPaths defines the json path under status field to be synced.",
                          "items": {
                            "properties": {
                              "name": {
                                "description": "Name represents the alias name for this field",
                                "type": "string"
                              },
                              "path": {
                                "description": "Path represents the json path of the field under status.\nThe path must point to a field with single value in the type of integer, bool or string.\nIf the path points to a non-existing field, no value will be returned.\nIf the path points to a structure, map or slice, no value will be returned and the status conddition\nof StatusFeedBackSynced will be set as false.\nRef to https://kubernetes.io/docs/reference/kubectl/jsonpath/ on how to write a jsonPath.",
                                "type": "string"
                              },
                              "version": {
                                "description": "Version is the version of the Kubernetes resource.\nIf it is not specified, the resource with the semantically latest version is\nused to resolve the path.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "name",
                              "path"
                            ],
                            "type": "object",
                            "additionalProperties": false
                          },
                          "type": "array",
                          "x-kubernetes-list-map-keys": [
                            "name"
                          ],
                          "x-kubernetes-list-type": "map"
                        },
                        "type": {
                          "description": "Type defines the option of how status can be returned.\nIt can be jsonPaths or wellKnownStatus.\nIf the type is JSONPaths, user should specify the jsonPaths field\nIf the type is WellKnownStatus, certain common fields of status defined by a rule only\nfor types in in k8s.io/api and open-cluster-management/api will be reported,\nIf these status fields do not exist, no values will be reported.",
                          "enum": [
                            "WellKnownStatus",
                            "JSONPaths"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array"
                  },
                  "resourceIdentifier": {
                    "description": "ResourceIdentifier represents the group, resource, name and namespace of a resoure.\niff this refers to a resource not created by this manifest work, the related rules will not be executed.",
                    "properties": {
                      "group": {
                        "description": "Group is the API Group of the Kubernetes resource,\nempty string indicates it is in core group.",
                        "type": "string"
                      },
                      "name": {
                        "description": "Name is the name of the Kubernetes resource.",
                        "type": "string"
                      },
                      "namespace": {
                        "description": "Name is the namespace of the Kubernetes resource, empty string indicates\nit is a cluster scoped resource.",
                        "type": "string"
                      },
                      "resource": {
                        "description": "Resource is the resource name of the Kubernetes resource.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "name",
                      "resource"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  },
                  "updateStrategy": {
                    "description": "UpdateStrategy defines the strategy to update this manifest. UpdateStrategy is Update\nif it is not set.",
                    "properties": {
                      "serverSideApply": {
                        "description": "serverSideApply defines the configuration for server side apply. It is honored only when the\ntype of the updateStrategy is ServerSideApply",
                        "properties": {
                          "fieldManager": {
                            "default": "work-agent",
                            "description": "FieldManager is the manager to apply the resource. It is work-agent by default, but can be other name with work-agent\nas the prefix.",
                            "pattern": "^work-agent",
                            "type": "string"
                          },
                          "force": {
                            "description": "Force represents to force apply the manifest.",
                            "type": "boolean"
                          },
                          "ignoreFields": {
                            "description": "IgnoreFields defines a list of json paths in the resource that will not be updated on the spoke.",
                            "items": {
                              "properties": {
                                "condition": {
                                  "default": "OnSpokePresent",
                                  "description": "Condition defines the condition that the fields should be ignored when apply the resource.\nFields in JSONPaths are all ignored when condition is met, otherwise no fields is ignored\nin the apply operation.",
                                  "enum": [
                                    "OnSpokePresent",
                                    "OnSpokeChange"
                                  ],
                                  "type": "string"
                                },
                                "jsonPaths": {
                                  "description": "JSONPaths defines the list of json path in the resource to be ignored",
                                  "items": {
                                    "type": "string"
                                  },
                                  "minItems": 1,
                                  "type": "array"
                                }
                              },
                              "required": [
                                "condition",
                                "jsonPaths"
                              ],
                              "type": "object",
                              "additionalProperties": false
                            },
                            "type": "array",
                            "x-kubernetes-list-map-keys": [
                              "condition"
                            ],
                            "x-kubernetes-list-type": "map"
                          }
                        },
                        "type": "object",
                        "additionalProperties": false
                      },
                      "type": {
                        "default": "Update",
                        "description": "type defines the strategy to update this manifest, default value is Update.\nUpdate type means to update resource by an update call.\nCreateOnly type means do not update resource based on current manifest.\nServerSideApply type means to update resource using server side apply with work-controller as the field manager.\nIf there is conflict, the related Applied condition of manifest will be in the status of False with the\nreason of ApplyConflict.\nReadOnly type means the agent will only check the existence of the resource based on its metadata,\nstatusFeedBackRules can still be used to get feedbackResults.",
                        "enum": [
                          "Update",
                          "CreateOnly",
                          "ServerSideApply",
                          "ReadOnly"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  }
                },
                "required": [
                  "resourceIdentifier"
                ],
                "type": "object",
                "additionalProperties": false
              },
              "type": "array"
            },
            "workload": {
              "description": "Workload represents the manifest workload to be deployed on a managed cluster.",
              "properties": {
                "manifests": {
                  "description": "Manifests represents a list of kuberenetes resources to be deployed on a managed cluster.",
                  "items": {
                    "description": "Manifest represents a resource to be deployed on managed cluster.",
                    "type": "object",
                    "x-kubernetes-embedded-resource": true,
                    "x-kubernetes-preserve-unknown-fields": true
                  },
                  "type": "array"
                }
              },
              "type": "object",
              "additionalProperties": false
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "registration": {
          "description": "Registration holds the registration configuration for the addon",
          "items": {
            "description": "RegistrationSpec describes how to register an addon agent to the hub cluster.\nWith the registration defined, The addon agent can access to kube apiserver with kube style API\nor other endpoints on hub cluster with client certificate authentication. During the addon\nregistration process, a csr will be created for each Registration on the hub cluster. The\nCSR will be approved automatically, After the csr is approved on the hub cluster, the klusterlet\nagent will create a secret in the installNamespace for the addon agent.\nIf the RegistrationType type is KubeClient, the secret name will be \"{addon name}-hub-kubeconfig\"\nwhose content includes key/cert and kubeconfig. Otherwise, If the RegistrationType type is\nCustomSigner the secret name will be \"{addon name}-{signer name}-client-cert\" whose content\nincludes key/cert.",
            "properties": {
              "customSigner": {
                "description": "CustomSigner holds the configuration of the CustomSigner type registration\nrequired when the Type is CustomSigner",
                "properties": {
                  "signerName": {
                    "description": "signerName is the name of signer that addon agent will use to create csr.",
                    "maxLength": 571,
                    "minLength": 5,
                    "pattern": "^([a-z0-9][a-z0-9-]*[a-z0-9]\\.)+[a-z]+\\/[a-z0-9-\\.]+$",
                    "type": "string"
                  },
                  "signingCA": {
                    "description": "SigningCA represents the reference of the secret on the hub cluster to sign the CSR\nthe secret type must be \"kubernetes.io/tls\"\nNote: The addon manager will not have permission to access the secret by default, so\nthe user must grant the permission to the addon manager(by creating rolebinding/clusterrolebinding\nfor the addon-manager serviceaccount \"addon-manager-controller-sa\").",
                    "properties": {
                      "name": {
                        "description": "Name of the signing CA secret",
                        "type": "string"
                      },
                      "namespace": {
                        "description": "Namespace of the signing CA secret, the namespace of the addon-manager will be used if it is not set.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "name"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  },
                  "subject": {
                    "description": "Subject is the user subject of the addon agent to be registered to the hub.\nIf it is not set, the addon agent will have the default subject\n\"subject\": {\n  \"user\": \"system:open-cluster-management:cluster:{clusterName}:addon:{addonName}:agent:{agentName}\",\n  \"groups: [\"system:open-cluster-management:cluster:{clusterName}:addon:{addonName}\",\n            \"system:open-cluster-management:addon:{addonName}\", \"system:authenticated\"]\n}",
                    "properties": {
                      "groups": {
                        "description": "groups is the user group of the addon agent.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "organizationUnit": {
                        "description": "organizationUnit is the ou of the addon agent",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "user": {
                        "description": "user is the user name of the addon agent.",
                        "type": "string"
                      }
                    },
                    "type": "object",
                    "additionalProperties": false
                  }
                },
                "required": [
                  "signerName",
                  "signingCA"
                ],
                "type": "object",
                "additionalProperties": false
              },
              "kubeClient": {
                "description": "KubeClient holds the configuration of the KubeClient type registration",
                "properties": {
                  "hubPermissions": {
                    "description": "HubPermissions represent the permission configurations of the addon agent to access the hub cluster",
                    "items": {
                      "description": "HubPermissionConfig configures the permission of the addon agent to access the hub cluster.\nWill create a RoleBinding in the same namespace as the managedClusterAddon to bind the user\nprovided ClusterRole/Role to the \"system:open-cluster-management:cluster:<cluster-name>:addon:<addon-name>\"\nGroup.",
                      "properties": {
                        "currentCluster": {
                          "description": "CurrentCluster contains the configuration of CurrentCluster type binding.\nIt is required when the type is CurrentCluster.",
                          "properties": {
                            "clusterRoleName": {
                              "description": "ClusterRoleName is the name of the clusterrole the addon agent is bound. A rolebinding\nwill be created referring to this cluster role in each cluster namespace.\nThe user must make sure the clusterrole exists on the hub cluster.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "clusterRoleName"
                          ],
                          "type": "object",
                          "additionalProperties": false
                        },
                        "singleNamespace": {
                          "description": "SingleNamespace contains the configuration of SingleNamespace type binding.\nIt is required when the type is SingleNamespace",
                          "properties": {
                            "namespace": {
                              "description": "Namespace is the namespace the addon agent has permissions to bind to. A rolebinding\nwill be created in this namespace referring to the RoleRef.",
                              "type": "string"
                            },
                            "roleRef": {
                              "description": "RoleRef is an reference to the permission resource. it could be a role or a cluster role,\nthe user must make sure it exist on the hub cluster.",
                              "properties": {
                                "apiGroup": {
                                  "description": "APIGroup is the group for the resource being referenced",
                                  "type": "string"
                                },
                                "kind": {
                                  "description": "Kind is the type of resource being referenced",
                                  "type": "string"
                                },
                                "name": {
                                  "description": "Name is the name of resource being referenced",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "apiGroup",
                                "kind",
                                "name"
                              ],
                              "type": "object",
                              "x-kubernetes-map-type": "atomic",
                              "additionalProperties": false
                            }
                          },
                          "required": [
                            "namespace",
                            "roleRef"
                          ],
                          "type": "object",
                          "additionalProperties": false
                        },
                        "type": {
                          "description": "Type of the permissions setting. It defines how to bind the roleRef on the hub cluster. It can be:\n- CurrentCluster: Bind the roleRef to the namespace with the same name as the managedCluster.\n- SingleNamespace: Bind the roleRef to the namespace specified by SingleNamespaceBindingConfig.",
                          "enum": [
                            "CurrentCluster",
                            "SingleNamespace"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "type": {
                "description": "Type of the registration configuration, it supports:\n- KubeClient: the addon agent can access the hub kube apiserver with kube style API.\n  the signer name should be \"kubernetes.io/kube-apiserver-client\". When this type is\n  used, the KubeClientRegistrationConfig can be used to define the permission of the\n  addon agent to access the hub cluster\n- CustomSigner: the addon agent can access the hub cluster through user-defined endpoints.\n  When this type is used, the CustomSignerRegistrationConfig can be used to define how\n  to issue the client certificate for the addon agent.",
                "enum": [
                  "KubeClient",
                  "CustomSigner"
                ],
                "type": "string"
              }
            },
            "required": [
              "type"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        }
      },
      "required": [
        "addonName",
        "agentSpec"
      ],
      "type": "object",
      "additionalProperties": false
    }
  },
  "required": [
    "spec"
  ],
  "type": "object"
}
