{
  "description": "LinstorSatelliteConfiguration is the Schema for the linstorsatelliteconfigurations 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": "LinstorSatelliteConfigurationSpec defines a partial, desired state of a LinstorSatelliteSpec.\n\nAll the LinstorSatelliteConfiguration resources with matching NodeSelector will\nbe merged into a single LinstorSatelliteSpec.",
      "properties": {
        "deletionPolicy": {
          "description": "DeletionPolicy configures the way LinstorSatellite resources are deleted.\n\nA LinstorSatellite may be deleted because:\n* It no longer matches the affinity and node selector of the LinstorCluster resource.\n* The node it references has been removed from Kubernetes.\n* It was manually deleted outside the Operator.\n\nA LinstorSatellite may store the last copy of a volume, in which case it is not desirable to unconditionally remove\nthe satellite from the cluster. For this reason, the following deletion policies exist:\n\n* DeletionPolicyEvacuate will start evacuation of the LINSTOR Satellite and wait until it completes before removing the LinstorSatellite object, comparable to the \"linstor node evacuate\" command.\n* DeletionPolicyRetain will retain the LINSTOR Satellite, keeping it registered in LINSTOR, but removing associated Kubernetes resources.\n* DeletionPolicyDelete will remove the LINSTOR Satellite from the LINSTOR Cluster without prior eviction, comparable to the \"linstor node lost\" command.",
          "enum": [
            "Evacuate",
            "Retain",
            "Delete"
          ],
          "type": "string"
        },
        "internalTLS": {
          "description": "InternalTLS configures secure communication for the LINSTOR Satellite.\n\nIf set, the control traffic between LINSTOR Controller and Satellite will be encrypted using mTLS.",
          "nullable": true,
          "properties": {
            "caReference": {
              "description": "CAReference configures the CA certificate to use when validating TLS certificates.\nIf not set, the TLS secret is expected to contain a \"ca.crt\" containing the CA certificate.",
              "properties": {
                "key": {
                  "default": "ca.crt",
                  "description": "Key to select in the resource.\nDefaults to ca.crt if not specified.",
                  "type": "string"
                },
                "kind": {
                  "default": "Secret",
                  "description": "Kind of the resource containing the CA Certificate, either a ConfigMap or Secret.",
                  "enum": [
                    "ConfigMap",
                    "Secret"
                  ],
                  "type": "string"
                },
                "name": {
                  "description": "Name of the resource containing the CA Certificate.",
                  "type": "string"
                },
                "optional": {
                  "description": "Optional specifies whether the resource and its key must exist.",
                  "type": "boolean"
                }
              },
              "required": [
                "name"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "certManager": {
              "description": "CertManager references a cert-manager Issuer or ClusterIssuer.\nIf set, a Certificate resource will be created, provisioning the secret references in SecretName using the\nissuer configured here.",
              "properties": {
                "group": {
                  "description": "Group of the resource being referred to.",
                  "type": "string"
                },
                "kind": {
                  "description": "Kind of the resource being referred to.",
                  "type": "string"
                },
                "name": {
                  "description": "Name of the resource being referred to.",
                  "type": "string"
                }
              },
              "required": [
                "name"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "secretName": {
              "description": "SecretName references a secret holding the TLS key and certificates.",
              "type": "string"
            },
            "tlsHandshakeDaemon": {
              "description": "TLSHandshakeDaemon enables tlshd for establishing TLS sessions for use by DRBD.\n\nIf enabled, adds a new sidecar to the LINSTOR Satellite that runs the tlshd handshake daemon.\nThe daemon uses the TLS certificate and key to establish secure connections on behalf of DRBD.",
              "type": "boolean"
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "ipFamilies": {
          "description": "IPFamilies configures the IP Family (IPv4 or IPv6) to use to connect to the LINSTOR Satellite.\n\nIf set, the control traffic between LINSTOR Controller and Satellite will use only the given IP Family.\nIf not set, the Operator will configure all families found in the Satellites Pods' Status.",
          "items": {
            "description": "IPFamily represents the IP Family (IPv4 or IPv6).",
            "enum": [
              "IPv4",
              "IPv6"
            ],
            "type": "string"
          },
          "type": "array"
        },
        "nodeAffinity": {
          "description": "NodeAffinity selects which LinstorSatellite resources this spec should be applied to.\nSee https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
          "properties": {
            "nodeSelectorTerms": {
              "description": "Required. A list of node selector terms. The terms are ORed.",
              "items": {
                "description": "A null or empty node selector term matches no objects. The requirements of\nthem are ANDed.\nThe TopologySelectorTerm type implements a subset of the NodeSelectorTerm.",
                "properties": {
                  "matchExpressions": {
                    "description": "A list of node selector requirements by node's labels.",
                    "items": {
                      "description": "A node selector requirement is a selector that contains values, a key, and an operator\nthat relates the key and values.",
                      "properties": {
                        "key": {
                          "description": "The label key that the selector applies to.",
                          "type": "string"
                        },
                        "operator": {
                          "description": "Represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.",
                          "type": "string"
                        },
                        "values": {
                          "description": "An array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. If the operator is Gt or Lt, the values\narray must have a single element, which will be interpreted as an integer.\nThis array is replaced during a strategic merge patch.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array",
                          "x-kubernetes-list-type": "atomic"
                        }
                      },
                      "required": [
                        "key",
                        "operator"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array",
                    "x-kubernetes-list-type": "atomic"
                  },
                  "matchFields": {
                    "description": "A list of node selector requirements by node's fields.",
                    "items": {
                      "description": "A node selector requirement is a selector that contains values, a key, and an operator\nthat relates the key and values.",
                      "properties": {
                        "key": {
                          "description": "The label key that the selector applies to.",
                          "type": "string"
                        },
                        "operator": {
                          "description": "Represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.",
                          "type": "string"
                        },
                        "values": {
                          "description": "An array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. If the operator is Gt or Lt, the values\narray must have a single element, which will be interpreted as an integer.\nThis array is replaced during a strategic merge patch.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array",
                          "x-kubernetes-list-type": "atomic"
                        }
                      },
                      "required": [
                        "key",
                        "operator"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array",
                    "x-kubernetes-list-type": "atomic"
                  }
                },
                "type": "object",
                "x-kubernetes-map-type": "atomic",
                "additionalProperties": false
              },
              "type": "array",
              "x-kubernetes-list-type": "atomic"
            }
          },
          "required": [
            "nodeSelectorTerms"
          ],
          "type": "object",
          "x-kubernetes-map-type": "atomic",
          "additionalProperties": false
        },
        "nodeSelector": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "NodeSelector selects which LinstorSatellite resources this spec should be applied to.\nSee https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
          "type": "object"
        },
        "patches": {
          "description": "Patches is a list of kustomize patches to apply.\n\nSee https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/ for how to create patches.",
          "items": {
            "description": "Patch represent either a Strategic Merge Patch or a JSON patch and its targets.",
            "properties": {
              "options": {
                "additionalProperties": {
                  "type": "boolean"
                },
                "description": "Options is a list of options for the patch",
                "type": "object"
              },
              "patch": {
                "description": "Patch is the content of a patch.",
                "minLength": 1,
                "type": "string"
              },
              "target": {
                "description": "Target points to the resources that the patch is applied to",
                "properties": {
                  "annotationSelector": {
                    "description": "AnnotationSelector is a string that follows the label selection expression\nhttps://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api\nIt matches against the resource annotations.",
                    "type": "string"
                  },
                  "group": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string"
                  },
                  "labelSelector": {
                    "description": "LabelSelector is a string that follows the label selection expression\nhttps://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api\nIt matches against the resource labels.",
                    "type": "string"
                  },
                  "name": {
                    "description": "Name of the resource.",
                    "type": "string"
                  },
                  "namespace": {
                    "description": "Namespace the resource belongs to, if it can belong to a namespace.",
                    "type": "string"
                  },
                  "version": {
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              }
            },
            "required": [
              "patch"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        },
        "podTemplate": {
          "description": "Template to apply to Satellite Pods.\n\nThe template is applied as a patch to the default resource, so it can be \"sparse\", not listing any\ncontainers or volumes that should remain unchanged.\nSee https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates",
          "type": "object",
          "x-kubernetes-map-type": "atomic",
          "x-kubernetes-preserve-unknown-fields": true
        },
        "properties": {
          "description": "Properties is a list of properties to set on the node.",
          "items": {
            "properties": {
              "expandFrom": {
                "description": "ExpandFrom can reference multiple resource fields at once.\nIt either sets the property to an aggregate value based on matched resource fields, or expands to multiple\nproperties.",
                "properties": {
                  "delimiter": {
                    "description": "Delimiter used to join multiple key and value pairs together.",
                    "type": "string"
                  },
                  "nameTemplate": {
                    "description": "NameTemplate defines how the property key is expanded.\nIf set, the template is appended to the defined property name, creating multiple properties instead of one\naggregate.\n* $1 is replaced with the matched key.\n* $2 is replaced with the matched value.",
                    "type": "string"
                  },
                  "nodeFieldRef": {
                    "description": "Select a field of the node. Supports `metadata.name`, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "valueTemplate": {
                    "description": "ValueTemplate defines how the property value is expanded.\n* $1 is replaced with the matched key.\n* $2 is replaced with the matched value.",
                    "type": "string"
                  }
                },
                "required": [
                  "nodeFieldRef"
                ],
                "type": "object",
                "additionalProperties": false
              },
              "name": {
                "description": "Name of the property to set.",
                "minLength": 1,
                "type": "string"
              },
              "optional": {
                "description": "Optional values are only set if they have a non-empty value",
                "type": "boolean"
              },
              "value": {
                "description": "Value to set the property to.",
                "type": "string"
              },
              "valueFrom": {
                "description": "ValueFrom sets the value from an existing resource.",
                "properties": {
                  "nodeFieldRef": {
                    "description": "Select a field of the node. Supports `metadata.name`, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`.",
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "nodeFieldRef"
                ],
                "type": "object",
                "additionalProperties": false
              }
            },
            "required": [
              "name"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "name"
          ],
          "x-kubernetes-list-type": "map"
        },
        "storagePools": {
          "description": "StoragePools is a list of storage pools to configure on the node.",
          "items": {
            "properties": {
              "filePool": {
                "description": "Configures a file system based storage pool, allocating a regular file per volume.",
                "properties": {
                  "directory": {
                    "description": "Directory is the path to the host directory used to store volume data.",
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "fileThinPool": {
                "description": "Configures a file system based storage pool, allocating a sparse file per volume.",
                "properties": {
                  "directory": {
                    "description": "Directory is the path to the host directory used to store volume data.",
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "lvmPool": {
                "description": "Configures a LVM Volume Group as storage pool.",
                "properties": {
                  "volumeGroup": {
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "lvmThinPool": {
                "description": "Configures a LVM Thin Pool as storage pool.",
                "properties": {
                  "thinPool": {
                    "description": "ThinPool is the name of the thinpool LV (without VG prefix).",
                    "type": "string"
                  },
                  "volumeGroup": {
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "name": {
                "description": "Name of the storage pool in linstor.",
                "minLength": 3,
                "type": "string"
              },
              "properties": {
                "description": "Properties to set on the storage pool.",
                "items": {
                  "properties": {
                    "expandFrom": {
                      "description": "ExpandFrom can reference multiple resource fields at once.\nIt either sets the property to an aggregate value based on matched resource fields, or expands to multiple\nproperties.",
                      "properties": {
                        "delimiter": {
                          "description": "Delimiter used to join multiple key and value pairs together.",
                          "type": "string"
                        },
                        "nameTemplate": {
                          "description": "NameTemplate defines how the property key is expanded.\nIf set, the template is appended to the defined property name, creating multiple properties instead of one\naggregate.\n* $1 is replaced with the matched key.\n* $2 is replaced with the matched value.",
                          "type": "string"
                        },
                        "nodeFieldRef": {
                          "description": "Select a field of the node. Supports `metadata.name`, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "valueTemplate": {
                          "description": "ValueTemplate defines how the property value is expanded.\n* $1 is replaced with the matched key.\n* $2 is replaced with the matched value.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "nodeFieldRef"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "name": {
                      "description": "Name of the property to set.",
                      "minLength": 1,
                      "type": "string"
                    },
                    "optional": {
                      "description": "Optional values are only set if they have a non-empty value",
                      "type": "boolean"
                    },
                    "value": {
                      "description": "Value to set the property to.",
                      "type": "string"
                    },
                    "valueFrom": {
                      "description": "ValueFrom sets the value from an existing resource.",
                      "properties": {
                        "nodeFieldRef": {
                          "description": "Select a field of the node. Supports `metadata.name`, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`.",
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "nodeFieldRef"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object",
                  "additionalProperties": false
                },
                "type": "array",
                "x-kubernetes-list-map-keys": [
                  "name"
                ],
                "x-kubernetes-list-type": "map"
              },
              "source": {
                "properties": {
                  "hostDevices": {
                    "description": "HostDevices is a list of device paths used to configure the given pool.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "zfsPool": {
                "description": "Configures a ZFS system based storage pool, allocating zvols from the given zpool.",
                "properties": {
                  "zPool": {
                    "description": "ZPool is the name of the ZFS zpool.",
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "zfsThinPool": {
                "description": "Configures a ZFS system based storage pool, allocating sparse zvols from the given zpool.",
                "properties": {
                  "zPool": {
                    "description": "ZPool is the name of the ZFS zpool.",
                    "type": "string"
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "additionalProperties": false
            },
            "required": [
              "name"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        },
        "additionalProperties": false
      },
      "type": "object",
      "additionalProperties": false
    },
    "status": {
      "description": "LinstorSatelliteConfigurationStatus defines the observed state of LinstorSatelliteConfiguration",
      "properties": {
        "conditions": {
          "description": "Current LINSTOR Satellite Config state",
          "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",
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        }
      },
      "type": "object",
      "additionalProperties": false
    }
  },
  "type": "object"
}
