Custom resources

IBM® Automation foundation uses Kubernetes custom resources (CRs) for configuration. All the CRs are in the API groups that end with automation.ibm.com. These API groups have a version of v1beta1.

The following custom resources are used by IBM Automation foundation:

Custom resource kind Purpose
AutomationUIConfig Defines the configuration of the platform user interface
AutomationBase Defines an instance of the IBM Automation foundation

The custom resource definitions (CRDs) for these kinds are declared in IBM Automation foundation's ClusterServiceVersion.

More custom resources that are used internally are available, which you might encounter for more advanced configuration tasks.

As with any Kubernetes resource, these custom resources contain the following elements:

Note the following points:

Configuring TLS certificates and secrets

All IBM Automation foundation resources that configure connections (AutomationBase, AutomationUIConfig, EventProcessor) have the same configuration options for TLS. Inside a tls section within the custom resource specification.

TLS certificates and secrets can be configured in two ways.

Note: A third mechanism exists to configure TLS certificates and secrets, which are available only in the AutomationUIConfig CR.

1. Using generated self-signed certificates and secrets

If the tls value in CR is defined as in the following snippet, then the Operator for that CR generates a self-signed CA certificate and the leaf certificates by using the IBM Cert Manager.

apiVersion: core.automation.ibm.com/v1beta1
  kind: AutomationUIConfig (AutomationBase, EventProcessor)
  metadata:
    name: iaf-system
  spec:
    ...
    tls: {}

The certificates generated this way is automatically mounted and renewed by IBM Cert Manager without the need for any user interaction.

2. Providing a custom certificate Issuer

You can pre-create (that is after you install Operators but before you create any custom resources) an IBM Cert Manager Issuer and set it in the tls section of the CRs as shown in the following snippet. The Operator for the CR will then use the provided Issuer to generate the leaf certificates instead of creating a self-signed CA certificate.

tls:
  issuerRef:
    name: <user_created_issuer>
  caSecret:
    key: ca.crt
    secretName: <user_created_ca_secret>

For this configuration to work with applications consuming IBM Automation foundation, the caSecret section must also be completed with a reference to a secret containing the public CA certificate, which trusts the certificate that is provided in the Issuer. Thus, completing the chain (if the Issuer was configured with a root CA then the two certificates are the same, the same secret that was used to create the Issuer can also be used here, if appropriate). This value is used to inform them of the public CA certificate they must trust.

Therefore, by using this mechanism an Issuer can be provided, which contains a root or intermediate signing certificate chain and key, which is used to generate leaf certificates for the IBM Automation foundation components, and a separate secret can be provided in caSecret, which contains only a copy of the root CA public key to inform the consuming application on how to trust IBM Automation foundation components.

The certificates that are generated by this Issuer are automatically mounted and renewed by IBM Cert Manager without any need for user interaction. Management of the provided issuer is left to the user.

3. Providing a custom certificate for Platform UI

You can use your custom certificates (ca.crt, cert.crt, and cert.key) with Platform UI.

You can either use certificates that are obtained from another provider or create them manually by using a tool such as openssl

  1. Create a secret with the name external-tls-secret in the IBM Automation foundation namespace before you create the AutomationUIConfig CR, by using the following command.

     oc create secret generic external-tls-secret --from-file=cert.crt=./cert.crt --from-file=cert.key=./cert.key --from-file=ca.crt=./ca.crt
    
  2. Configure the AutomationUIConfig CR as follows:

     tls: 
       certificateSecret: 
         secretName: external-tls-secret
       caSecret:
           secretName: external-tls-secret
           key: ca.crt
    

This configuration ensures that Platform UI's NGINX pods use the custom certificates that you configured with the external-tls-secret.

Note:

You need to manually restart the IBM Platform UI ibm-nginx- pods in your project namespace. Manually restarting the ibm-nginx- pods can be achieved by issuing the following command. Note: Ensure to replace <iaf-project> in the following command with the namespace or project where you installed IBM Automation foundation.

oc delete pod -l component=ibm-nginx -n <iaf-project>

When you use this configuration the certificates that are placed in the external-tls-secret are managed by the user. Therefore, renewal or replacement is left to the user.

Configuring IBM Automation foundation to have a common CA for all components

By default TLS is specified as tls: {} in IBM Automation foundation, which means that each AutomationBase, AutomationUIConfig, and EventProcessor has a separate and distinct CA and certificate chain. To configure a common CA for each component, a custom Issuer must be provided. This can be the same Issuer for each component. That Issuer can also be configured to be self-signed if desired.

AutomationUIConfig

The AutomationUIConfig custom resource is used to override the default configuration for the Platform UI. The default configuration uses the cluster default storage class and self-signed certificates.

Key points about the AutomationUIConfig CR

Note: If you want to override the default configuration, the AutomationUIConfig custom resource must be created before any Cloud Paks or other extensions are created.

AutomationUIConfig CustomResourceDefinition

AutomationUIConfig YAML structure

The AutomationUIConfig definition is organized in the following structure:

apiVersion: core.automation.ibm.com/v1beta1
kind: AutomationUIConfig
metadata: ~
spec: 
  tls: 
    caSecret: 
      key: ~
      secretName: ~
    certificateSecret: 
      secretName: ~
    issuerRef: 
      group: ~
      kind: ~
      name: ~
    storage: 
      class: ~
      deleteClaim: ~
      overrides: ~
      selector: ~
      size: ~
      type: ~

AutomationUIConfig details

The following structure provides the definition for each of the keys and their expected values.

Note: When creating a custom AutomationUIConfig definition, you must specify a valid storage class for Platform UI (Zen).

Providing Custom Parameters to Zen

This feature enables the user to provide customized parameters to Zen. Following are the list of parameters that are supported and included as in the official Zen documentation. For more information, see Keys and Default Values for ZenService Custom Resource. These parameters need to be added in the AutomationUIConfig CR as shown below:

spec:
   zenService:
      csNamespace: ibm-common-services
      acceptRollback: N/A / true / false
      cert_manager_enabled: N/A / true / false
      cloudpakfordata: N/A / true / false
      generateAdminPassword: N/A / false / true
      iamIntegration: false / true
      ignoreForMaintenance: N/A / true
      scaleConfig: N/A / small / medium / large / xlarge (for x86_64 only)
      storageClass: (Primary Storage Class)
      zenCoreMetaDbStorageClass: (Secondary Storage Class)
      storageVendor: portworx / ocs
      version: N/A / 4.4.0 (version in format x.x.x)
      zen_vault_enabled: N/A / false / true
      userHomeSC: (storage class for userHome)
      zenCustomRoute:
          route_host: (Customized zen route)
      enableTopologyZone: N/A / false / true
      enableTopologyRegion: N/A / false / true
      customizedTopologyKey: N/A / (String type)
      nodeTaints: N/A / (String type)

All the fields given in the spec are optional and the user can specify the required parameters as mentioned in Zen documentation.

Custom route might be enabled using zenCustomRoute field as shown in the preceding spec. The route_host can be specified under it to get the customized Zen route. The certs and secrets for the same would be managed by the tls field. Hence there is no need to add other fields under zenCustomRoute except the route_host. For customized Zen route, on prem (fyre clusters) it should be in the format <your-custom-route-name>.<apps.domain-name-of-cluster>. For example, my-zen-route.apps.my-cluster.cp.fyre.ibm.com. For SaaS, it should be of the format <your-custom-route-name>.<Availability-Zone>.<domain-name>. For example, test-zen-ui.us-south.containers.appdomain.cloud.

For more information, see custom certificates for Zen.

Note: Further information regarding Zen Route is available in the Custom CloudPak Platform UI (Zen) Route section.

storageClass: The user can provide the storageClass inside the ZenService field or in the Storage field inside the spec (like it is done currently). Both fields cannot be enabled simultaneously. But while specifying the ZenService field, it is mandatory to add storageClass inside it, as ZenService takes the precedence and only parameters defined inside it will be considered. Otherwise, ZenService CR will show an error.

Example,

spec:
  storage:
    class: <Your_managed-nfs-storage>

Few points to be considered regarding zen and zenService field:

AutomationBase

The AutomationBase CR represents an instance of IBM Automation foundation that is installed into a Kubernetes namespace. Cartridges are associated with an instance of this custom resource.

This custom resource contains the instance-wide configuration information, which currently includes the following kinds of information:

The IBM Automation foundation operator uses the status of this CR to report its endpoints, status, and conditions, following Kubernetes operator best practices.

AutomationBase CustomResourceDefinition

AutomationBase YAML structure

The AutomationBase definition is organized in the following structure:

apiVersion: base.automation.ibm.com/v1beta1
kind: AutomationBase
metadata: ~
spec: 
  apicurio: 
    config: ~
    image: ~
    imagePullPolicy: ~
    resources: ~
  elasticsearch: 
    additionalAllowedAPIs: ~
    license: 
      accept: ~
    monitoring: 
      template: 
        pod: 
          spec: 
            affinity: 
              nodeAffinity: ~
              podAffinity: ~
              podAntiAffinity: ~
            containers: 
              image: ~
              imagePullPolicy: ~
              livenessProbe: ~
              name: ~
              readinessProbe: ~
              resources: ~
            tolerations: ~
    nodegroupspecs: 
      config: 
        key: ~
        value: ~
      name: ~
      nodeSelector: ~
      replicas: ~
      storage: 
        class: ~
        fsGroup: ~
        selector: ~
        size: ~
        supplementalGroups: ~
        volumeClaimTemplate: ~
      template: 
        pod: 
          spec: 
            affinity: 
              nodeAffinity: ~
              podAffinity: ~
              podAntiAffinity: ~
            containers: 
              image: ~
              imagePullPolicy: ~
              livenessProbe: ~
              name: ~
              readinessProbe: ~
              resources: ~
            tolerations: ~
    snapshotStores: 
      name: ~
      storage: 
        class: ~
        fsGroup: ~
        selector: ~
        size: ~
        supplementalGroups: ~
        volumeClaimTemplate: ~
    tls: 
      caSecret: 
        key: ~
        secretName: ~
      issuerRef: ~
    version: ~
  kafka: ~
  license: 
    accept: ~
  status: 
    components: 
      apicurio: 
        endpoints: 
          name: ~
          scope: ~
          type: ~
          uri: 
            caSecret: ~
            key: ~
            secretName: ~
      elasticsearch: 
        endpoints: 
          authentication: 
            secret: 
              secretName: ~
            type: ~
          caSecret: 
            key: ~
            secretName: ~
          name: ~
          scope: ~
          type: ~
          uri: ~
      kafka: 
        endpoints: 
          authentication: 
            secret: 
              secretName: ~
            type: ~
          bootstrapServers: ~
          caSecret: 
            key: ~
            secretName: ~
          name: ~
          scope: ~
          type: ~
    conditions: ~
    managedResources: ~
  tls: 
    caSecret: 
      key: ~
      secretName: ~
    issuerRef: 
      group: ~
      kind: ~
      name: ~

AutomationBase details

AutomationBase sample YAML

apiVersion: base.automation.ibm.com/v1beta1
kind: AutomationBase
metadata:
  name: sample
  namespace: iafdemo
spec:
  kafka:
    clientsCa:
      generateCertificateAuthority: false
    clusterCa:
      generateCertificateAuthority: false
    entityOperator:
      template:
        pod:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: kubernetes.io/arch
                        operator: In
                        values:
                          - amd64
                          - s390x
          metadata:
            annotations:
              productID: 068a62892a1e4db39641342e592daa25
              productMetric: FREE
              productName: IBM Cloud Platform Common Services
          securityContext:
            runAsNonRoot: true
        tlsSidecarContainer:
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: true
        topicOperatorContainer:
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: true
        userOperatorContainer:
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: true
      tlsSidecar:
        resources:
          limits:
            cpu: 500m
            memory: 128Mi
          requests:
            cpu: 500m
            memory: 128Mi
      topicOperator:
        resources:
          limits:
            cpu: '1'
            memory: 1Gi
          requests:
            cpu: '1'
            memory: 1Gi
      userOperator:
        resources:
          limits:
            cpu: '1'
            memory: 1Gi
          requests:
            cpu: '1'
            memory: 1Gi
    kafka:
      authorization:
        type: simple
      config:
        offsets.topic.replication.factor: 3
        transaction.state.log.min.isr: 2
        transaction.state.log.replication.factor: 3
      listeners:
        - name: plain
          port: 9092
          tls: false
          type: internal
        - authentication:
            type: scram-sha-512
          name: tls
          port: 9093
          tls: true
          type: internal
        - authentication:
            type: scram-sha-512
          name: external
          port: 9094
          tls: true
          type: route
      replicas: 3
      resources:
        limits:
          cpu: '2'
          memory: 4Gi
        requests:
          cpu: '2'
          memory: 4Gi
      storage:
        size: 10Gi
        type: persistent-claim
        class: ibmc-block-gold
      template:
        kafkaContainer:
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: true
        pod:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: kubernetes.io/arch
                        operator: In
                        values:
                          - amd64
                          - s390x
          metadata:
            annotations:
              productID: 068a62892a1e4db39641342e592daa25
              productMetric: FREE
              productName: IBM Cloud Platform Common Services
          securityContext:
            runAsNonRoot: true
    zookeeper:
      replicas: 3
      resources:
        limits:
          cpu: '1'
          memory: 2Gi
        requests:
          cpu: '1'
          memory: 2Gi
      storage:
        size: 10Gi
        type: persistent-claim
        class: ibmc-block-gold
      template:
        pod:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: kubernetes.io/arch
                        operator: In
                        values:
                          - amd64
                          - s390x
          metadata:
            annotations:
              productID: 068a62892a1e4db39641342e592daa25
              productMetric: FREE
              productName: IBM Cloud Platform Common Services
          securityContext:
            runAsNonRoot: true
        zookeeperContainer:
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: true
  license:
    accept: true
  tls: {}
  version: "v1.0"
  elasticsearch:
    license:
      accept: true
    version: "v1.0"
    nodegroupspecs:
      - name: master-data
        replicas: 3

For the complete Kafka configuration, see Kafka schema reference.

Note: While deleting AutomationBase and CartridgeRequirements, you will have to manually delete the corresponding KafkaComposite too. See Troubleshooting for more details.

elasticsearch:
  spec:
    license:
      accept: true
    nodegroupspecs:
      - name: master-data
        replicas: 3
        storage: {}
        template:
          pod:
            spec: {}
    tls:
      caSecret:
        key: ca.crt
        secretName: iaf-system-es-clst-cert
      issuerRef:
        name: iaf-system-es-cls-issuer
    version: "v1.0"

AutomationBase sample YAML

Here's an example:

apiVersion: base.automation.ibm.com/v1beta1
kind: AutomationBase
metadata:
  name: acme-iaf
  namespace: acme-iaf
spec:
  license:
    accept: true
  tls: {}
  elasticsearch: {}
  kafka: {}

AutomationBase status

The returned status section takes the following form:

status:
  components:
    elasticsearch:
      endpoints:
      - type: API
        name: external-route-https
        scope: External
        uri: https://iaf-system-es.acme-iaf.acme.com
        caSecret:
          secretName: iaf-system-es-tls-secret
          key: ca.crt
      - type: API
        scope: Internal
        name: internal-service-https
        uri: https://iaf-system-es.acme-iaf
        caSecret:
          secretName: iaf-system-es-tls-secret
          key: ca.crt
    kafka:
      endpoints:
      - type: Kafka
        name: internal-service-plain
        scope: Internal
        bootstrapServers: iaf-system-kafka.acme-iaf.svc:9092
      - type: Kafka
        name: internal-service-tls
        scope: External
        bootstrapServers: iaf-system-kafka.acme-iaf.svc:9093
        caSecret:
          secretName: iaf-system-kafka-tls-secret
          key: ca.crt
      - type: Kafka
        name: external-route-tls
        scope: External
        bootstrapServers: iaf-system-kafka.acme-iaf.acme.com:443
        caSecret:
          secretName: iaf-system-kafka-tls-secret
          key: ca.crt
  conditions:
    - lastTransitionTime: '2021-03-03T14:31:30Z'
      status: 'True'
      type: ApicurioReady
    - lastTransitionTime: '2021-03-03T14:29:19Z'
      status: 'True'
      type: BedrockReady
    - lastTransitionTime: '2021-03-03T14:29:19Z'
      status: 'True'
      type: ElasticReady
    - lastTransitionTime: '2021-03-03T14:31:28Z'
      status: 'True'
      type: KafkaReady
    - lastTransitionTime: '2021-03-03T14:31:30Z'
      message: AutomationBase instance successfully created
      reason: InstanceCreated
      status: 'True'
      type: Ready

The returned status section takes the following form:

status:
  conditions:
    - lastTransitionTime: '2021-03-03T14:12:08Z'
      message: AutomationUIConfig successfully registered
      reason: Registered
      status: 'True'
      type: Ready

Mutual TLS supporting Kafka

If the TLS authentication is provided in the AutomationBase CR, the user would be able to create the KafkaUser and the Kafka endpoint with mutual TLS (mTLS) authentication enabled. Multiple KafkaUsers can be created by giving different authentication types in AutomationBase CR as shown below.

Authentication

Note: The number of Kafka users created depends on the number of authentications with their configurations (internal or external) given in the AutomationBase CR.

KafkaUser CR sample YAML

The following example shows the KafkaUser CR structure:

apiVersion: ibmevents.ibm.com/v1beta2
kind: KafkaUser
metadata:
  generateName: cartridge-sample-kafka-auth-3-8dw8g-
  resourceVersion: '38557725'
  name: cartridge-sample-kafka-auth-3
  uid: cd896fed-ff1a-4adf-b18b-d24103dd0c72
  creationTimestamp: '2021-10-06T12:08:32Z'
  generation: 1
  managedFields:
    - apiVersion: ibmevents.ibm.com/v1beta1
      fieldsType: FieldsV1
      fieldsV1:
        'f:metadata':
          'f:generateName': {}
          'f:labels':
            .: {}
            'f:crossplane.io/claim-name': {}
            'f:crossplane.io/claim-namespace': {}
            'f:crossplane.io/composite': {}
            'f:ibmevents.ibm.com/cluster': {}
          'f:ownerReferences':
            .: {}
            'k:{"uid":"a7316d1a-7a40-4063-9bd9-54b185e11738"}':
              .: {}
              'f:apiVersion': {}
              'f:controller': {}
              'f:kind': {}
              'f:name': {}
              'f:uid': {}
        'f:spec':
          .: {}
          'f:authentication':
            .: {}
            'f:type': {}
          'f:authorization':
            .: {}
            'f:acls': {}
            'f:type': {}
      manager: crossplane
      operation: Update
      time: '2021-10-06T12:08:32Z'
    - apiVersion: ibmevents.ibm.com/v1beta1
      fieldsType: FieldsV1
      fieldsV1:
        'f:status':
          .: {}
          'f:conditions': {}
          'f:observedGeneration': {}
          'f:secret': {}
          'f:username': {}
      manager: okhttp
      operation: Update
      time: '2021-10-06T12:08:34Z'
  namespace: acme-iaf1
  ownerReferences:
    - apiVersion: shim.bedrock.ibm.com/v1alpha1
      controller: true
      kind: KafkaComposite
      name: cartridge-sample-kafka-auth-3-8dw8g
      uid: a7316d1a-7a40-4063-9bd9-54b185e11738
  labels:
    crossplane.io/claim-name: cartridge-sample-kafka-auth-3
    crossplane.io/claim-namespace: acme-iaf1
    crossplane.io/composite: cartridge-sample-kafka-auth-3-8dw8g
    ibmevents.ibm.com/cluster: iaf-system
spec:
  authentication:
    type: tls
  authorization:
    acls:
      - host: '*'
        operation: All
        resource:
          name: cartridge
          patternType: prefix
          type: topic
      - host: '*'
        operation: All
        resource:
          name: cartridge
          patternType: prefix
          type: group
      - host: '*'
        operation: Read
        resource:
          name: __schema_cartridge
          patternType: prefix
          type: topic
      - host: '*'
        operation: Alter
        resource:
          name: __schema_cartridge
          patternType: prefix
          type: topic
      - host: '*'
        operation: Describe
        resource:
          type: cluster
      - host: '*'
        operation: Read
        resource:
          name: __schema_
          patternType: prefix
          type: topic
    type: simple
status:
  conditions:
    - lastTransitionTime: '2021-10-06T12:08:33.285184329Z'
      status: 'True'
      type: Ready
  observedGeneration: 1
  secret: cartridge-sample-kafka-auth-3
  username: CN=cartridge-sample-kafka-auth-3

Kafka CR sample YAML

The following example shows the Kafka CR structure:

apiVersion: ibmevents.ibm.com/v1beta2
kind: Kafka
metadata:
  generateName: iaf-system-2fn68-
  resourceVersion: '38551681'
  name: iaf-system
  uid: 01c94455-c21a-4752-8a41-7892fbb01ddb
  creationTimestamp: '2021-10-06T11:58:52Z'
  generation: 1
  managedFields:
    - apiVersion: ibmevents.ibm.com/v1beta1
      fieldsType: FieldsV1
      fieldsV1:
        'f:metadata':
          'f:generateName': {}
          'f:labels':
            .: {}
            'f:crossplane.io/claim-name': {}
            'f:crossplane.io/claim-namespace': {}
            'f:crossplane.io/composite': {}
          'f:ownerReferences':
            .: {}
            'k:{"uid":"a6900af8-ee88-4870-ba50-8c6616e55c56"}':
              .: {}
              'f:apiVersion': {}
              'f:controller': {}
              'f:kind': {}
              'f:name': {}
              'f:uid': {}
        'f:spec':
          .: {}
          'f:clusterCa':
            .: {}
            'f:generateCertificateAuthority': {}
          'f:entityOperator':
            .: {}
            'f:template':
              .: {}
              'f:pod':
                .: {}
                'f:affinity':
                  .: {}
                  'f:nodeAffinity':
                    .: {}
                    'f:requiredDuringSchedulingIgnoredDuringExecution':
                      .: {}
                      'f:nodeSelectorTerms': {}
                'f:metadata':
                  .: {}
                  'f:annotations':
                    .: {}
                    'f:productID': {}
                    'f:productMetric': {}
                    'f:productName': {}
                'f:securityContext':
                  .: {}
                  'f:runAsNonRoot': {}
              'f:tlsSidecarContainer':
                .: {}
                'f:securityContext':
                  .: {}
                  'f:allowPrivilegeEscalation': {}
                  'f:capabilities':
                    .: {}
                    'f:drop': {}
                  'f:privileged': {}
                  'f:readOnlyRootFilesystem': {}
                  'f:runAsNonRoot': {}
              'f:topicOperatorContainer':
                .: {}
                'f:securityContext':
                  .: {}
                  'f:allowPrivilegeEscalation': {}
                  'f:capabilities':
                    .: {}
                    'f:drop': {}
                  'f:privileged': {}
                  'f:readOnlyRootFilesystem': {}
                  'f:runAsNonRoot': {}
              'f:userOperatorContainer':
                .: {}
                'f:securityContext':
                  .: {}
                  'f:allowPrivilegeEscalation': {}
                  'f:capabilities':
                    .: {}
                    'f:drop': {}
                  'f:privileged': {}
                  'f:readOnlyRootFilesystem': {}
                  'f:runAsNonRoot': {}
            'f:tlsSidecar':
              .: {}
              'f:resources':
                .: {}
                'f:limits':
                  .: {}
                  'f:cpu': {}
                  'f:memory': {}
                'f:requests':
                  .: {}
                  'f:cpu': {}
                  'f:memory': {}
            'f:topicOperator':
              .: {}
              'f:resources':
                .: {}
                'f:limits':
                  .: {}
                  'f:cpu': {}
                  'f:memory': {}
                'f:requests':
                  .: {}
                  'f:cpu': {}
                  'f:memory': {}
            'f:userOperator':
              .: {}
              'f:resources':
                .: {}
                'f:limits':
                  .: {}
                  'f:cpu': {}
                  'f:memory': {}
                'f:requests':
                  .: {}
                  'f:cpu': {}
                  'f:memory': {}
          'f:kafka':
            .: {}
            'f:authorization':
              .: {}
              'f:type': {}
            'f:config':
              .: {}
              'f:offsets.topic.replication.factor': {}
              'f:transaction.state.log.min.isr': {}
              'f:transaction.state.log.replication.factor': {}
            'f:listeners': {}
            'f:replicas': {}
            'f:resources':
              .: {}
              'f:limits':
                .: {}
                'f:cpu': {}
                'f:memory': {}
              'f:requests':
                .: {}
                'f:cpu': {}
                'f:memory': {}
            'f:storage':
              .: {}
              'f:size': {}
              'f:type': {}
            'f:template':
              .: {}
              'f:kafkaContainer':
                .: {}
                'f:securityContext':
                  .: {}
                  'f:allowPrivilegeEscalation': {}
                  'f:capabilities':
                    .: {}
                    'f:drop': {}
                  'f:privileged': {}
                  'f:readOnlyRootFilesystem': {}
                  'f:runAsNonRoot': {}
              'f:pod':
                .: {}
                'f:affinity':
                  .: {}
                  'f:nodeAffinity':
                    .: {}
                    'f:requiredDuringSchedulingIgnoredDuringExecution':
                      .: {}
                      'f:nodeSelectorTerms': {}
                'f:metadata':
                  .: {}
                  'f:annotations':
                    .: {}
                    'f:productID': {}
                    'f:productMetric': {}
                    'f:productName': {}
                'f:securityContext':
                  .: {}
                  'f:runAsNonRoot': {}
          'f:zookeeper':
            .: {}
            'f:replicas': {}
            'f:resources':
              .: {}
              'f:limits':
                .: {}
                'f:cpu': {}
                'f:memory': {}
              'f:requests':
                .: {}
                'f:cpu': {}
                'f:memory': {}
            'f:storage':
              .: {}
              'f:size': {}
              'f:type': {}
            'f:template':
              .: {}
              'f:pod':
                .: {}
                'f:affinity':
                  .: {}
                  'f:nodeAffinity':
                    .: {}
                    'f:requiredDuringSchedulingIgnoredDuringExecution':
                      .: {}
                      'f:nodeSelectorTerms': {}
                'f:metadata':
                  .: {}
                  'f:annotations':
                    .: {}
                    'f:productID': {}
                    'f:productMetric': {}
                    'f:productName': {}
                'f:securityContext':
                  .: {}
                  'f:runAsNonRoot': {}
              'f:zookeeperContainer':
                .: {}
                'f:securityContext':
                  .: {}
                  'f:allowPrivilegeEscalation': {}
                  'f:capabilities':
                    .: {}
                    'f:drop': {}
                  'f:privileged': {}
                  'f:readOnlyRootFilesystem': {}
                  'f:runAsNonRoot': {}
      manager: crossplane
      operation: Update
      time: '2021-10-06T11:58:52Z'
    - apiVersion: ibmevents.ibm.com/v1beta1
      fieldsType: FieldsV1
      fieldsV1:
        'f:status':
          .: {}
          'f:clusterId': {}
          'f:conditions': {}
          'f:listeners': {}
          'f:observedGeneration': {}
      manager: okhttp
      operation: Update
      time: '2021-10-06T12:02:29Z'
  namespace: acme-iaf1
  ownerReferences:
    - apiVersion: shim.bedrock.ibm.com/v1alpha1
      controller: true
      kind: KafkaComposite
      name: iaf-system-2fn68
      uid: a6900af8-ee88-4870-ba50-8c6616e55c56
  labels:
    crossplane.io/claim-name: iaf-system
    crossplane.io/claim-namespace: acme-iaf1
    crossplane.io/composite: iaf-system-2fn68
spec:
  clusterCa:
    generateCertificateAuthority: false
  entityOperator:
    template:
      pod:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
                - matchExpressions:
                    - key: kubernetes.io/arch
                      operator: In
                      values:
                        - amd64
                        - s390x
                        - ppc64le
        metadata:
          annotations:
            productID: 068a62892a1e4db39641342e592daa25
            productMetric: FREE
            productName: IBM Cloud Platform Common Services
        securityContext:
          runAsNonRoot: true
      tlsSidecarContainer:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - ALL
          privileged: false
          readOnlyRootFilesystem: false
          runAsNonRoot: true
      topicOperatorContainer:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - ALL
          privileged: false
          readOnlyRootFilesystem: false
          runAsNonRoot: true
      userOperatorContainer:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - ALL
          privileged: false
          readOnlyRootFilesystem: false
          runAsNonRoot: true
    tlsSidecar:
      resources:
        limits:
          cpu: 500m
          memory: 128Mi
        requests:
          cpu: 500m
          memory: 128Mi
    topicOperator:
      resources:
        limits:
          cpu: '1'
          memory: 1Gi
        requests:
          cpu: '1'
          memory: 1Gi
    userOperator:
      resources:
        limits:
          cpu: '1'
          memory: 1Gi
        requests:
          cpu: '1'
          memory: 1Gi
  kafka:
    authorization:
      type: simple
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.min.isr: 2
      transaction.state.log.replication.factor: 3
    listeners:
      - authentication:
          type: scram-sha-512
        name: scram
        port: 9093
        tls: true
        type: internal
      - authentication:
          type: scram-sha-512
        name: scramext
        port: 9094
        tls: true
        type: route
      - authentication:
          type: tls
        name: tls
        port: 9095
        tls: true
        type: internal
      - authentication:
          type: tls
        name: external
        port: 9096
        tls: true
        type: route
    replicas: 3
    resources:
      limits:
        cpu: '2'
        memory: 4Gi
      requests:
        cpu: '2'
        memory: 4Gi
    storage:
      size: 10Gi
      type: persistent-claim
    template:
      kafkaContainer:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - ALL
          privileged: false
          readOnlyRootFilesystem: false
          runAsNonRoot: true
      pod:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
                - matchExpressions:
                    - key: kubernetes.io/arch
                      operator: In
                      values:
                        - amd64
                        - s390x
                        - ppc64le
        metadata:
          annotations:
            productID: 068a62892a1e4db39641342e592daa25
            productMetric: FREE
            productName: IBM Cloud Platform Common Services
        securityContext:
          runAsNonRoot: true
  zookeeper:
    replicas: 3
    resources:
      limits:
        cpu: '1'
        memory: 2Gi
      requests:
        cpu: '1'
        memory: 2Gi
    storage:
      size: 10Gi
      type: persistent-claim
    template:
      pod:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
                - matchExpressions:
                    - key: kubernetes.io/arch
                      operator: In
                      values:
                        - amd64
                        - s390x
                        - ppc64le
        metadata:
          annotations:
            productID: 068a62892a1e4db39641342e592daa25
            productMetric: FREE
            productName: IBM Cloud Platform Common Services
        securityContext:
          runAsNonRoot: true
      zookeeperContainer:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - ALL
          privileged: false
          readOnlyRootFilesystem: false
          runAsNonRoot: true
status:
  clusterId: 5NZNlW74QgCnVO5BWmC3Jw
  conditions:
    - lastTransitionTime: '2021-10-06T12:02:28.922Z'
      status: 'True'
      type: Ready
  listeners:
    - addresses:
        - host: iaf-system-kafka-bootstrap.acme-iaf1.svc
          port: 9093
      bootstrapServers: 'iaf-system-kafka-bootstrap.acme-iaf1.svc:9093'
      certificates:
        - |
          -----BEGIN CERTIFICATE-----
          MIIDGzCCAgOgAwIBAgIRAIhYJOETxBquBUtF2wcUnH8wDQYJKoZIhvcNAQELBQAw
          JzElMCMGA1UEAxMcSUJNIEF1dG9tYXRpb24gRm91bmRhdGlvbiBDQTAeFw0yMTA5
          MjkwODEyMzBaFw0yMTEyMjgwODEyMzBaMCcxJTAjBgNVBAMTHElCTSBBdXRvbWF0
          aW9uIEZvdW5kYXRpb24gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
          AQCtYAaoVt6lU/SmRmEou/QxmzGwhzUQDWGBrfF/7cv5TkDhvLL7j5VMSw7g4how
          b8az+5xHGffFKyq+z2sPEvxrT0A0nfcUsaCT6b6/oWbaqh5vwkkP8lZnIQAfrauP
          yxzdofdjZMf/MBv6wxHZepacrgtDdV4enyQZcbCZWbRMCYmhCnUdbJWxj+jucAYw
          egJUf79ZPuPIp/XZnTKuvNUQQ1PQud71j4KEstJNVnpqs3rmNA4ICL1ZpEsk3XrN
          Qqviv9zlBpqcIizCdAiQP9XueYZC4V5Bz9vM00xyVzppjhAByw5Meb2F0MbuGLM+
          TvUOObci5Dq2jgGLLOuUek+FAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIChDAPBgNV
          HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQwbYVtkeUFY6NeJLBKd72waDsW7TANBgkq
          hkiG9w0BAQsFAAOCAQEAEACxQa/pqTu8CJs8nN/h2UE5+Pxo2tuOMyV26ohuy+i2
          /1sMvRFNAqzpeb5qD/7hdAtN9JK3+znbCmArLGASNFebS5E5yASN1R76IyBQgHHA
          x3sKIRnquxdw4kjgWZTndHTij7NDTMHotYdTsDJyc4u6/oKgtU0pBNQLuGSL6PNu
          bRt+r8mAyZximHNkHYXrb7MFLhLXd0TRAt9TxKPFCW7T280iuP70tXLlU9ysbX0e
          fC1bvggwgXR6yXxe500zc68qlPaKdeJQDXOwEl+OxSnocE0iZ21zyEG53EoYw5MB
          ktavTFervY6lFyZxLj6mHC7v9fIkj49Tb2ObuoUDsw==
          -----END CERTIFICATE-----
      type: scram
    - addresses:
        - host: iaf-system-kafka-bootstrap.acme-iaf1.svc
          port: 9095
      bootstrapServers: 'iaf-system-kafka-bootstrap.acme-iaf1.svc:9095'
      certificates:
        - |
          -----BEGIN CERTIFICATE-----
          MIIDGzCCAgOgAwIBAgIRAIhYJOETxBquBUtF2wcUnH8wDQYJKoZIhvcNAQELBQAw
          JzElMCMGA1UEAxMcSUJNIEF1dG9tYXRpb24gRm91bmRhdGlvbiBDQTAeFw0yMTA5
          MjkwODEyMzBaFw0yMTEyMjgwODEyMzBaMCcxJTAjBgNVBAMTHElCTSBBdXRvbWF0
          aW9uIEZvdW5kYXRpb24gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
          AQCtYAaoVt6lU/SmRmEou/QxmzGwhzUQDWGBrfF/7cv5TkDhvLL7j5VMSw7g4how
          b8az+5xHGffFKyq+z2sPEvxrT0A0nfcUsaCT6b6/oWbaqh5vwkkP8lZnIQAfrauP
          yxzdofdjZMf/MBv6wxHZepacrgtDdV4enyQZcbCZWbRMCYmhCnUdbJWxj+jucAYw
          egJUf79ZPuPIp/XZnTKuvNUQQ1PQud71j4KEstJNVnpqs3rmNA4ICL1ZpEsk3XrN
          Qqviv9zlBpqcIizCdAiQP9XueYZC4V5Bz9vM00xyVzppjhAByw5Meb2F0MbuGLM+
          TvUOObci5Dq2jgGLLOuUek+FAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIChDAPBgNV
          HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQwbYVtkeUFY6NeJLBKd72waDsW7TANBgkq
          hkiG9w0BAQsFAAOCAQEAEACxQa/pqTu8CJs8nN/h2UE5+Pxo2tuOMyV26ohuy+i2
          /1sMvRFNAqzpeb5qD/7hdAtN9JK3+znbCmArLGASNFebS5E5yASN1R76IyBQgHHA
          x3sKIRnquxdw4kjgWZTndHTij7NDTMHotYdTsDJyc4u6/oKgtU0pBNQLuGSL6PNu
          bRt+r8mAyZximHNkHYXrb7MFLhLXd0TRAt9TxKPFCW7T280iuP70tXLlU9ysbX0e
          fC1bvggwgXR6yXxe500zc68qlPaKdeJQDXOwEl+OxSnocE0iZ21zyEG53EoYw5MB
          ktavTFervY6lFyZxLj6mHC7v9fIkj49Tb2ObuoUDsw==
          -----END CERTIFICATE-----
      type: tls
    - addresses:
        - host: >-
            iaf-system-kafka-scramext-bootstrap-acme-iaf1.apps.peehu.cp.fyre.ibm.com
          port: 443
      bootstrapServers: >-
        iaf-system-kafka-scramext-bootstrap-acme-iaf1.apps.peehu.cp.fyre.ibm.com:443
      certificates:
        - |
          -----BEGIN CERTIFICATE-----
          MIIDGzCCAgOgAwIBAgIRAIhYJOETxBquBUtF2wcUnH8wDQYJKoZIhvcNAQELBQAw
          JzElMCMGA1UEAxMcSUJNIEF1dG9tYXRpb24gRm91bmRhdGlvbiBDQTAeFw0yMTA5
          MjkwODEyMzBaFw0yMTEyMjgwODEyMzBaMCcxJTAjBgNVBAMTHElCTSBBdXRvbWF0
          aW9uIEZvdW5kYXRpb24gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
          AQCtYAaoVt6lU/SmRmEou/QxmzGwhzUQDWGBrfF/7cv5TkDhvLL7j5VMSw7g4how
          b8az+5xHGffFKyq+z2sPEvxrT0A0nfcUsaCT6b6/oWbaqh5vwkkP8lZnIQAfrauP
          yxzdofdjZMf/MBv6wxHZepacrgtDdV4enyQZcbCZWbRMCYmhCnUdbJWxj+jucAYw
          egJUf79ZPuPIp/XZnTKuvNUQQ1PQud71j4KEstJNVnpqs3rmNA4ICL1ZpEsk3XrN
          Qqviv9zlBpqcIizCdAiQP9XueYZC4V5Bz9vM00xyVzppjhAByw5Meb2F0MbuGLM+
          TvUOObci5Dq2jgGLLOuUek+FAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIChDAPBgNV
          HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQwbYVtkeUFY6NeJLBKd72waDsW7TANBgkq
          hkiG9w0BAQsFAAOCAQEAEACxQa/pqTu8CJs8nN/h2UE5+Pxo2tuOMyV26ohuy+i2
          /1sMvRFNAqzpeb5qD/7hdAtN9JK3+znbCmArLGASNFebS5E5yASN1R76IyBQgHHA
          x3sKIRnquxdw4kjgWZTndHTij7NDTMHotYdTsDJyc4u6/oKgtU0pBNQLuGSL6PNu
          bRt+r8mAyZximHNkHYXrb7MFLhLXd0TRAt9TxKPFCW7T280iuP70tXLlU9ysbX0e
          fC1bvggwgXR6yXxe500zc68qlPaKdeJQDXOwEl+OxSnocE0iZ21zyEG53EoYw5MB
          ktavTFervY6lFyZxLj6mHC7v9fIkj49Tb2ObuoUDsw==
          -----END CERTIFICATE-----
      type: scramext
    - addresses:
        - host: >-
            iaf-system-kafka-external-bootstrap-acme-iaf1.apps.peehu.cp.fyre.ibm.com
          port: 443
      bootstrapServers: >-
        iaf-system-kafka-external-bootstrap-acme-iaf1.apps.peehu.cp.fyre.ibm.com:443
      certificates:
        - |
          -----BEGIN CERTIFICATE-----
          MIIDGzCCAgOgAwIBAgIRAIhYJOETxBquBUtF2wcUnH8wDQYJKoZIhvcNAQELBQAw
          JzElMCMGA1UEAxMcSUJNIEF1dG9tYXRpb24gRm91bmRhdGlvbiBDQTAeFw0yMTA5
          MjkwODEyMzBaFw0yMTEyMjgwODEyMzBaMCcxJTAjBgNVBAMTHElCTSBBdXRvbWF0
          aW9uIEZvdW5kYXRpb24gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
          AQCtYAaoVt6lU/SmRmEou/QxmzGwhzUQDWGBrfF/7cv5TkDhvLL7j5VMSw7g4how
          b8az+5xHGffFKyq+z2sPEvxrT0A0nfcUsaCT6b6/oWbaqh5vwkkP8lZnIQAfrauP
          yxzdofdjZMf/MBv6wxHZepacrgtDdV4enyQZcbCZWbRMCYmhCnUdbJWxj+jucAYw
          egJUf79ZPuPIp/XZnTKuvNUQQ1PQud71j4KEstJNVnpqs3rmNA4ICL1ZpEsk3XrN
          Qqviv9zlBpqcIizCdAiQP9XueYZC4V5Bz9vM00xyVzppjhAByw5Meb2F0MbuGLM+
          TvUOObci5Dq2jgGLLOuUek+FAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIChDAPBgNV
          HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQwbYVtkeUFY6NeJLBKd72waDsW7TANBgkq
          hkiG9w0BAQsFAAOCAQEAEACxQa/pqTu8CJs8nN/h2UE5+Pxo2tuOMyV26ohuy+i2
          /1sMvRFNAqzpeb5qD/7hdAtN9JK3+znbCmArLGASNFebS5E5yASN1R76IyBQgHHA
          x3sKIRnquxdw4kjgWZTndHTij7NDTMHotYdTsDJyc4u6/oKgtU0pBNQLuGSL6PNu
          bRt+r8mAyZximHNkHYXrb7MFLhLXd0TRAt9TxKPFCW7T280iuP70tXLlU9ysbX0e
          fC1bvggwgXR6yXxe500zc68qlPaKdeJQDXOwEl+OxSnocE0iZ21zyEG53EoYw5MB
          ktavTFervY6lFyZxLj6mHC7v9fIkj49Tb2ObuoUDsw==
          -----END CERTIFICATE-----
      type: external
  observedGeneration: 1