adc apply

Определение

Считывает один или несколько документов (каждый документ может содержать несколько конфигураций объектов, разделенных строкой ---), генерирует объекты Kubernetes для каждой предоставленной конфигурации и применяет их на стороне сервера. Имена созданных ресурсов составляются из конфигурационного параметра metadata.name и опционально передаваемого префикса. Данная команда является идемпотентной.

Сгенерированная конфигурация зависит от параметра kind:

  • Для кластера (ImpalaCluster, TrinoCluster, SparkApplication, SparkHistoryServer) генерируется CR соответствующего оператора и необходимые секреты. Для SparkHistoryServer дополнительно генерируется секрет <metadata.name>-spark-history-properties.

  • Для оператора (ImpalaOperator, TrinoOperator, SparkOperator, KerberosOperator) генерируются Namespace, ServiceAccount, RBAC, Deployment, секрет для загрузки образа (если предоставлен) и объекты CRD.

  • Для Helm-конфигураций (Celeborn, YuniKorn) напрямую генерируются объекты workload:

    • Celeborn — StatefulSets, Service, ConfigMap, RBAC;

    • YuniKorn — k8shim Deployment, ConfigMap, RBAC.

Использование

$ adc apply --file <file> [--file <file>...] \
                          [--kubeconfig <kubeconfig>] \
                          [--prefix <prefix>] \
                          [--dry-run] \
                          [--only-crds | --only-rbac]
Аргументы
Параметр Описание

-f, --file

Путь к конфигурационному YAML-файлу. Можно предоставить несколько файлов, повторив флаг

-k, --kubeconfig

Путь к файлу kubeconfig. Значение по умолчанию — $KUBECONFIG

-p, --prefix

Префикс, который будет использован перед metadata.name для сгенерированного имени ресурса

--dry-run

Выводит сгенерированный манифест объекта, не применяя его. По умолчанию вывод не содержит конфигурацию объектов CRD

--only-crds

Генерирует или применяет только конфигурацию объектов CustomResourceDefinition. Не совместим с --only-rbac

--only-rbac

Генерирует или применяет только конфигурацию объектов ServiceAccount, Role, RoleBinding, ClusterRole и ClusterRoleBinding. Не совместим с --only-crds

Примеры

Оператор Trino

Генерация манифеста оператора Trino с перенаправлением вывода в файл trino-operator-render.yaml:

$ adc apply -f trino-operator.yaml --dry-run > trino-operator-render.yaml

Сгенерированный манифест не содержит конфигурацию объектов CRD.

trino-operator-render.yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: trino-operator
spec: {}
status: {}
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: trino-operator
  namespace: trino-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: trino-operator-trino-operator-manager
  namespace: trino-operator
rules:
- apiGroups:
  - events.k8s.io
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - trino.arenadata.io
  resources:
  - clusters
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - trino.arenadata.io
  resources:
  - clusters/status
  verbs:
  - get
  - patch
  - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: trino-operator-trino-operator-manager
  namespace: trino-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: trino-operator-trino-operator-manager
subjects:
- kind: ServiceAccount
  name: trino-operator
  namespace: trino-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: trino-operator-trino-operator-payload
  namespace: trino-operator
rules:
- apiGroups:
  - events.k8s.io
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - ""
  resources:
  - secrets
  - services
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - apps
  resources:
  - deployments
  - statefulsets
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - trino.arenadata.io
  resources:
  - clusters
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - trino.arenadata.io
  resources:
  - clusters/status
  verbs:
  - get
  - patch
  - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: trino-operator-trino-operator-payload
  namespace: trino-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: trino-operator-trino-operator-payload
subjects:
- kind: ServiceAccount
  name: trino-operator
  namespace: trino-operator
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: operator
    app.kubernetes.io/managed-by: adc-cli
    arenadata.io/operator-type: trino
  name: trino-operator-trino-operator
  namespace: trino-operator
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: operator
      app.kubernetes.io/managed-by: adc-cli
      app.kubernetes.io/name: trino-operator-trino-operator
  strategy: {}
  template:
    metadata:
      labels:
        app.kubernetes.io/component: operator
        app.kubernetes.io/managed-by: adc-cli
        app.kubernetes.io/name: trino-operator-trino-operator
    spec:
      containers:
      - args:
        - -ns=trino-operator
        image: hub.adsw.io/ng/trino-operator:1.58.0
        imagePullPolicy: Always
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
          initialDelaySeconds: 5
          periodSeconds: 10
        name: app
        readinessProbe:
          httpGet:
            path: /readyz
            port: 8081
          initialDelaySeconds: 5
          periodSeconds: 10
        resources:
          limits:
            cpu: 500m
            memory: 256Mi
          requests:
            cpu: 500m
            memory: 256Mi
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
          runAsGroup: 10001
          runAsNonRoot: true
          runAsUser: 10001
      securityContext:
        fsGroup: 10001
        runAsGroup: 10001
        runAsNonRoot: true
        runAsUser: 10001
      serviceAccountName: trino-operator
      terminationGracePeriodSeconds: 10
status: {}

Применение конфигурации оператора Trino:

$ adc apply -f trino-operator.yaml

Кластер Trino

Генерация манифеста кластера Trino с перенаправлением вывода в файл trino-cluster-render.yaml:

$ adc apply -f trino-cluster.yaml --dry-run > trino-cluster-render.yaml
trino-cluster-render.yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: trino-configs
  namespace: trino
stringData:
  core-site.xml: |-
    <configuration>
      <property>
        <name>dfs.client.failover.proxy.provider.adh</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider</value>
      </property>
      <property>
        <name>dfs.ha.namenodes.adh</name>
        <value>nn_tsn-adh-k8s-1,nn_tsn-adh-k8s-3</value>
      </property>
      <property>
        <name>dfs.namenode.rpc-address.adh.nn_tsn-k8s-1</name>
        <value>tsn-adh-k8s-1.ru-central1.internal:8020</value>
      </property>
      <property>
        <name>dfs.namenode.rpc-address.adh.nn_tsn-k8s-3</name>
        <value>tsn-adh-k8s-3.ru-central1.internal:8020</value>
      </property>
      <property>
        <name>dfs.nameservices</name>
        <value>adh</value>
      </property>
      <property>
        <name>fs.defaultFS</name>
        <value>hdfs://adh</value>
      </property>
      <property>
        <name>hadoop.proxyuser.trino.groups</name>
        <value>*</value>
      </property>
      <property>
        <name>hadoop.proxyuser.trino.hosts</name>
        <value>*</value>
      </property>
      <property>
        <name>hadoop.security.authentication</name>
        <value>simple</value>
      </property>
      <property>
        <name>ozone.om.address.adh.om_tsn-k8s-1</name>
        <value>tsn-adh-k8s-1.ru-central1.internal:9862</value>
      </property>
      <property>
        <name>ozone.om.address.adh.om_tsn-k8s-2</name>
        <value>tsn-adh-k8s-2.ru-central1.internal:9862</value>
      </property>
      <property>
        <name>ozone.om.address.adh.om_tsn-k8s-3</name>
        <value>tsn-adh-k8s-3.ru-central1.internal:9862</value>
      </property>
      <property>
        <name>ozone.om.nodes.adh</name>
        <value>om_tsn-adh-k8s-1,om_tsn-adh-k8s-2,om_tsn-adh-k8s-3</value>
      </property>
      <property>
        <name>ozone.om.service.ids</name>
        <value>adhom</value>
      </property>
    </configuration>
type: Opaque
---
apiVersion: trino.arenadata.io/v1alpha1
kind: Cluster
metadata:
  name: trino
  namespace: trino
spec:
  configsSecretName: trino-configs
  coordinator:
    metadata: {}
    replicas: 1
    spec:
      image: hub.adsw.io/adh-enterprise/trino-docker:476_arenadata2-adh-4.2.0-x86_64
      imagePullPolicy: Always
  worker:
    metadata: {}
    replicas: 1
    spec:
      image: hub.adsw.io/adh-enterprise/trino-docker:476_arenadata2-adh-4.2.0-x86_64
      imagePullPolicy: Always
status: {}

Применение конфигурации кластера Trino:

$ adc apply -f trino-cluster.yaml

RBAC приложения Spark

  1. Инициализируйте приложение Spark:

    $ adc init --spark-application -o spark-application.yaml
    spark-application.yaml
    apiVersion: adc.arenadata.io/v1alpha1
    kind: SparkApplication
    metadata:
      name: spark-application
      namespace: spark-applications
    spec:
      image: hub.arenadata.io/adc-enterprise/spark3:3.5.4.4-adc-1.4.0
    
      ## Image pull secret for a private registry.
      ## Set 'externalSecretName' to reference an existing Secret,
      ## or set 'credentials' and optionally 'secretName' to let the CLI create one.
      #imagePullSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-registry-secret
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-registry-secret
      #
      #  #credentials:
      #  #  registry: registry.example.com
      #  #  username: user
      #  #  password: pass
    
      #hadoop:
      #  core:
      #    fs.defaultFS: ""
      #  hdfs:
      #    dfs.encrypt.data.transfer.cipher.suites: AES/CTR/NoPadding
      #  hive:
      #    hive.metastore.uris: ""
    
      ## Kerberos configuration for authentication.
      #kerberos:
      #  principal: user@EXAMPLE.COM
      #
      #  # CLI reads the local files and creates the kerberos-ccache Secret on 'adc apply'.
      #  # Alternative - keytab mode: replace this block with:
      #  #   keytab:
      #  #     secretName: <name-of-existing-keytab-secret>
      #  ticketCache:
      #    #secretName: custom-ticket-cache
      #    externalSecretName: existing-ticket-cache
      #    #ticketPath: /tmp/krb5cc_1000
      #    #krb5ConfPath: /etc/krb5.conf
    
      ## Ranger plugin configuration.
      ## Uncomment and fill the lines below. adc apply derives the rest.
      #ranger:
      #  # fill ranger.plugin.spark.policy.rest.url below with Ranger endpoint, e.g. https://adps-adc.ru-central1.internal:6182
      #  # fill ranger.plugin.spark.service.name below with Ranger service name you want to use for product, e.g. adc_spark_id_1
      #  security:
      #    ranger.plugin.spark.policy.rest.url: ""
      #    ranger.plugin.spark.service.name: ""
      #
      #  # fill xasecure.audit.destination.solr.zookeepers below with Zookeepers endpoints to resolve solr service, e.g. adps-adc.ru-central1.internal:2181/Arenadata.Hadoop-2.solr.server
      #  audit:
      #    xasecure.audit.destination.solr.zookeepers: ""
      #
      #  # Local Ranger files 'adc apply' writes into the configs Secret.
      #  # Relative paths are resolved against the config file.
      #  files:
      #    jceksStorePath: /path/to/ranger.jceks
    
      ## Java KeyStore/TrustStore certificate configuration.
      ## Set externalSecretName to reference an existing Secret,
      ## or set files and optional secretName to have ADC create it.
      #ssl:
      #  ## Name of the Secret containing Java keystores.
      #  #secretName: custom-ssl-secret
      #  externalSecretName: existing-ssl-secret
      #
      #  # Key in the Secret containing the truststore file.
      #  trustStoreKey: truststore.jks
      #
      #  ## Password for the truststore (optional).
      #  #trustStorePassword: bigdata
      #
      #  ## Key in the Secret containing the keystore file (optional).
      #  #keyStoreKey: keystore.jks
      #
      #  ## Password for the keystore (optional).
      #  #keyStorePassword: bigdata
      #
      #  ## Local files 'adc apply' puts into the Secret named by ssl.secretName.
      #  ## Relative paths are resolved against the config file.
      #  #files:
      #  #  trustStorePath: /path/to/truststore.jks
      #  #  #keyStorePath: /path/to/keystore.jks
    
      ## Use an external Hadoop configs Secret instead of the one rendered by ADC.
      #hadoopConfigsSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-spark-hadoop-configs
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-spark-hadoop-configs
    
      ## Use an external Ranger configs Secret instead of the one rendered by ADC.
      #rangerConfigsSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-spark-ranger-configs
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-spark-ranger-configs
    
      # Spark application main resource (e.g. local:///opt/spark/examples/jars/spark-examples.jar).
      mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.13-3.5.4.4-4.3.0-2.jar"
    
      ## HDFS or local directory for the Spark event log.
      ## When set, the CLI adds spark.eventLog.enabled=true, spark.eventLog.dir,
      ## spark.eventLog.rolling.enabled=true and spark.eventLog.rolling.interval=30s to sparkConf.
      #eventLogDir: ""
    
      ## Fully-qualified main class name. Required for Java/Scala applications.
      mainClass: "org.apache.spark.examples.SparkPi"
    
      # ServiceAccount used by the Spark driver, also injected into
      # spark.kubernetes.authenticate.driver.serviceAccountName. The CLI creates it, plus a Role
      # and RoleBinding for Spark pods, by default (create: true). Set create: false to skip that
      # and only reference a ServiceAccount managed elsewhere.
      # The Role rules are managed by the CLI and cannot be customized.
      serviceAccount:
        create: true
        name: spark-application
      job:
        ## true (default) deletes the spark-submit Job pod after it finishes; set false to keep it for debugging.
        #deleteOnTermination: true
    
        #resources:
        #  limits:
        #    cpu: "1"
        #    memory: 512Mi
        #  requests:
        #    cpu: 500m
        #    memory: 64Mi
    
        ## Component arguments. Key-value pairs passed to the component configuration.
        #args:
        #  executor-memory: 1g
        #  num-executors: "2"
    
      ## Application arguments appended after mainApplicationFile.
      #args:
      #  - "100"
    
      # Spark configuration entries (spark.*).
      sparkConf:
        spark.artifactory.dir.path: /tmp/artifacts
        spark.jars.ivy: /tmp/ivy
        spark.local.dir: /tmp/data
        spark.sql.catalog.spark_catalog: org.apache.iceberg.spark.SparkSessionCatalog
        spark.sql.extensions: org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
        spark.sql.security.confblacklist: spark.sql.extensions
    
      ## Seconds after the application finishes (Succeeded, or Failed with no
      ## retries left) before the SparkApplication is deleted. Omit to keep it
      ## until explicit deletion.
      #ttlSecondsAfterFinished: 3600
    
      ## Celeborn remote shuffle service for Spark.
      ## tiers mirror the cluster's storage.tiers: local (SSD/HDD) and MEMORY advertise their name only,
      ## remote (S3/HDFS) also set dir (and, for S3, credentials). Ozone is an HDFS tier with an ofs:// dir.
      #celeborn:
      #  # Storage tiers mirroring the cluster's storage.tiers so the client advertises the same layers.
      #  # type: SSD, HDD, S3, HDFS, MEMORY. SSD/HDD and MEMORY are advertise-only here (no dir; worker-only
      #  # fields ignored); remote S3/HDFS set dir (s3a:// for S3; hdfs:// or ofs:// for Ozone on HDFS). Example:
      #  #   - type: MEMORY   # cache tier; pair with a durable tier below, no dir
      #  #   - type: SSD      # advertise-only on the client, no dir needed
      #  #   - dir: s3a://bucket/celeborn
      #  #     s3: { endpoint: https://s3:9878, region: us-east-1 }
      #  #     type: S3
      #  #   - dir: hdfs://nn/celeborn   # or ofs://om/volume/bucket/celeborn for Ozone
      #  #     type: HDFS
      #  tiers:
      #    - dir: s3a://shuffle/my-cluster
      #      s3:
      #        accessKey: <access-key>
      #        endpoint: https://s3.endpoint:443
      #        pathStyleAccess: true
      #        region: <region>
      #        secretKey: <secret-key>
      #      type: S3
      #  masterEndpoint: ""
      #  extraSparkConf:
      #    spark.sql.adaptive.enabled: "true"
      #
      #  # Enable TLS on the client's RPC connection to the Celeborn cluster.
      #  # When true the CLI renders spark.celeborn.ssl.* into the Spark conf
      #  # and requires the ssl section with trustStoreKey.
      #  rpcEncryption: false
      #
      #  # Enable TLS on the client's data module, which carries shuffle push/fetch
      #  # traffic between executors and workers. Requires the ssl section with trustStoreKey.
      #  dataEncryption: false
    
      ## YuniKorn scheduler configuration for queue selection and Gang scheduling.
      ## Uncomment the block to route the Spark job into a YuniKorn queue; the CLI renders the
      ## scheduler name, queue labels and gang annotations into sparkConf.
      #yunikorn:
      #  queue: root.analytics
      #  taskGroups:
      #    - minMember: 1
      #      minResource:
      #        cpu: "1"
      #        memory: 1433Mi
      #      name: spark-driver
      #    - minMember: 2
      #      minResource:
      #        cpu: "1"
      #        memory: 1433Mi
      #      name: spark-executor
    
      ## Monitoring configuration.
      #monitoring:
      #  # Enables Prometheus metrics export from this product's pods.
      #  exportMetrics: true
  2. Сгенерируйте только настройки RBAC:

    $ adc apply -f spark-application.yaml --only-rbac --dry-run > spark-application-rbac.yaml
    spark-application-rbac.yaml
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: spark-application
      namespace: spark-applications
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: spark-application
      namespace: spark-applications
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - configmaps
      - persistentvolumeclaims
      - services
      - secrets
      verbs:
      - get
      - list
      - watch
      - create
      - update
      - patch
      - delete
      - deletecollection
    - apiGroups:
      - networking.k8s.io
      resources:
      - networkpolicies
      verbs:
      - get
      - list
      - watch
      - create
      - update
      - patch
      - delete
    - apiGroups:
      - events.k8s.io
      resources:
      - events
      verbs:
      - create
      - patch
      - update
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: spark-application
      namespace: spark-applications
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: spark-application
    subjects:
    - kind: ServiceAccount
      name: spark-application
      namespace: spark-applications

CRD-схемы оператора Kerberos

Сгенерируйте только CRD-схемы оператора Kerberos:

$ adc apply -f kerberos-operator.yaml --only-crds --dry-run > kerberos-operator-crds.yaml
kerberos-operator-crds.yaml
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.20.0
  name: kdcconfigs.krb5.arenadata.io
spec:
  group: krb5.arenadata.io
  names:
    kind: KDCConfig
    listKind: KDCConfigList
    plural: kdcconfigs
    singular: kdcconfig
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - jsonPath: .spec.realm
      name: Realm
      type: string
    - jsonPath: .status.conditions[?(@.type=="Ready")].reason
      name: Status
      type: string
    - jsonPath: .metadata.creationTimestamp
      name: Age
      type: date
    name: v1alpha1
    schema:
      openAPIV3Schema:
        description: KDCConfig is the Schema for the kdcconfigs API.
        properties:
          apiVersion:
            description: |-
              APIVersion defines the versioned schema of this representation of an object.
              Servers should convert recognized schemas to the latest internal value, and
              may reject unrecognized values.
              More 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.
              Servers may infer this from the endpoint the client submits requests to.
              Cannot be updated.
              In CamelCase.
              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
            type: string
          metadata:
            type: object
          spec:
            description: KDCConfigSpec defines the desired state of KDCConfig.
            properties:
              domainRealm:
                additionalProperties:
                  type: string
                description: |-
                  DomainRealm maps domain names to Kerberos realms. This corresponds to
                  the [domain_realm] section in krb5.conf. Used for mapping DNS domain
                  names or hostnames to specific realms.
                  Example: {".example.com": "EXAMPLE.COM", "host.example.com": "EXAMPLE.COM"}
                type: object
              labelSelector:
                additionalProperties:
                  type: string
                description: |-
                  LabelSelector is used to select which secrets contain LDAP configuration
                  for keytab initialization. Only secrets matching this label selector
                  will be used for Kerberos keytab generation and initialization process.
                minProperties: 1
                type: object
              libdefaults:
                additionalProperties:
                  type: string
                description: |-
                  Libdefaults specifies default Kerberos library options. This corresponds
                  to the [libdefaults] section in krb5.conf. Contains key-value pairs for
                  settings like default encryption types, ticket lifetimes, and debug level.
                  Example: {"default_tgs_enctypes": "aes256-cts-hmac-sha1-96", "debug": "false"}
                type: object
              realm:
                description: |-
                  Realm is the Kerberos realm name. Must be uppercase and follow the
                  standard domain name format. Example: "EXAMPLE.COM"
                pattern: ^[A-Z][A-Z0-9.-]{2,254}$
                type: string
              realms:
                additionalProperties:
                  type: string
                description: |-
                  Realms defines the mapping between realm names and their KDC servers.
                  This corresponds to the [realms] section in krb5.conf. Each entry maps
                  a realm name to a string containing kdc, admin_server, and other
                  realm-specific settings.
                  Example: {"EXAMPLE.COM": "kdc = kerberos.example.com:88 admin_server = kerberos.example.com:749"}
                type: object
            required:
            - labelSelector
            - realm
            - realms
            type: object
          status:
            description: KDCConfigStatus defines the observed state of KDCConfig.
            properties:
              conditions:
                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.
                        This 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.
                        This may be an empty string.
                      maxLength: 32768
                      type: string
                    observedGeneration:
                      description: |-
                        observedGeneration represents the .metadata.generation that the condition was set based upon.
                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
                        with 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.
                        Producers of specific condition types may define expected values and meanings for this field,
                        and whether the values are considered a guaranteed API.
                        The value should be a CamelCase string.
                        This 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
                type: array
              lastError:
                type: string
            type: object
        required:
        - spec
        type: object
    served: true
    storage: true
    subresources:
      status: {}
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: null
  storedVersions: null
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.20.0
  name: keytabs.krb5.arenadata.io
spec:
  group: krb5.arenadata.io
  names:
    kind: Keytab
    listKind: KeytabList
    plural: keytabs
    singular: keytab
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - jsonPath: .status.conditions[?(@.type=="Rotation")].reason
      name: Rotation
      type: string
    - jsonPath: .status.conditions[?(@.type=="Generation")].reason
      name: Ready
      type: string
    - jsonPath: .metadata.creationTimestamp
      name: Age
      type: date
    - jsonPath: .status.conditions[?(@.type=="Rotation")].message
      name: NextRotation
      type: string
    name: v1alpha1
    schema:
      openAPIV3Schema:
        description: Keytab is the Schema for the keytabs API.
        properties:
          apiVersion:
            description: |-
              APIVersion defines the versioned schema of this representation of an object.
              Servers should convert recognized schemas to the latest internal value, and
              may reject unrecognized values.
              More 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.
              Servers may infer this from the endpoint the client submits requests to.
              Cannot be updated.
              In CamelCase.
              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
            type: string
          metadata:
            type: object
          spec:
            description: KeytabSpec defines the desired state of Keytab.
            properties:
              items:
                items:
                  description: KeytabItem defines a keytab entry for a specific Kerberos
                    realm.
                  properties:
                    labelSelector:
                      additionalProperties:
                        type: string
                      description: |-
                        LabelSelector is used to select secrets containing admin credentials
                        for authentication to the KDC. Only secrets matching this label selector
                        will be used to obtain the necessary credentials for keytab generation.
                      type: object
                    principals:
                      description: |-
                        List of principals for keytab generation.
                        Principal names are specified without @REALM. Example: service/pod-0.svc-name.ns.svc.cluster.local
                      items:
                        pattern: ^([^/@]+)(/([^@]+))$
                        type: string
                      minItems: 1
                      type: array
                    realm:
                      description: |-
                        Realm is the Kerberos realm name. Must be uppercase and follow the
                        standard domain name format. Example: "EXAMPLE.COM"
                      pattern: ^[A-Z][A-Z0-9.-]{2,254}$
                      type: string
                  required:
                  - principals
                  - realm
                  type: object
                minItems: 1
                type: array
              rotation:
                description: |-
                  Rotation policy defines the automatic key rotation schedule and behavior.
                  If specified, the keytab will be automatically regenerated according to
                  the policy rules. If omitted, no automatic rotation is performed.
                properties:
                  checkInterval:
                    default: 1h
                    description: |-
                      CheckInterval specifies how frequently the controller checks if
                      rotation is needed. This should be shorter than the main rotation
                      interval to ensure timely rotation.
                      Default: 1h (1 hour)
                    type: string
                  interval:
                    default: 720h
                    description: |-
                      Interval is the time duration between automatic keytab rotations.
                      After each interval, a new keytab with fresh keys is generated.
                      Default: 720h (30 days)
                    type: string
                type: object
                x-kubernetes-validations:
                - message: Interval must be positive
                  rule: '!has(self.interval) || duration(self.interval).getSeconds()
                    > 0'
                - message: CheckInterval must be positive
                  rule: '!has(self.checkInterval) || duration(self.checkInterval).getSeconds()
                    > 0'
                - message: CheckInterval must be less than Interval
                  rule: '!has(self.checkInterval) || !has(self.interval) || duration(self.checkInterval).getSeconds()
                    < duration(self.interval).getSeconds()'
            required:
            - items
            type: object
          status:
            description: KeytabStatus defines the observed state of Keytab.
            properties:
              conditions:
                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.
                        This 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.
                        This may be an empty string.
                      maxLength: 32768
                      type: string
                    observedGeneration:
                      description: |-
                        observedGeneration represents the .metadata.generation that the condition was set based upon.
                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
                        with 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.
                        Producers of specific condition types may define expected values and meanings for this field,
                        and whether the values are considered a guaranteed API.
                        The value should be a CamelCase string.
                        This 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
                type: array
              lastError:
                type: string
              lastRotationTime:
                format: date-time
                type: string
              rotationCount:
                type: integer
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: null
  storedVersions: null
Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней