---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.16.4
  creationTimestamp: "2025-10-27T11:29:55Z"
  generation: 1
  managedFields:
  - apiVersion: apiextensions.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:controller-gen.kubebuilder.io/version: {}
        f:ownerReferences:
          k:{"uid":"42934d21-bf48-4e6e-be5b-f538b0be0793"}: {}
      f:spec:
        f:group: {}
        f:names:
          f:kind: {}
          f:listKind: {}
          f:plural: {}
          f:singular: {}
        f:scope: {}
        f:versions: {}
    manager: cluster-network-operator/operconfig
    operation: Apply
    time: "2025-10-27T11:29:55Z"
  - apiVersion: apiextensions.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        f:acceptedNames:
          f:kind: {}
          f:listKind: {}
          f:plural: {}
          f:singular: {}
        f:conditions:
          k:{"type":"Established"}:
            .: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"NamesAccepted"}:
            .: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
    manager: kube-apiserver
    operation: Update
    subresource: status
    time: "2025-10-27T11:29:55Z"
  name: userdefinednetworks.k8s.ovn.org
  ownerReferences:
  - apiVersion: operator.openshift.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: Network
    name: cluster
    uid: 42934d21-bf48-4e6e-be5b-f538b0be0793
  resourceVersion: "4429"
  uid: 2b196ab6-f115-49f8-9750-d992211ccc01
spec:
  conversion:
    strategy: None
  group: k8s.ovn.org
  names:
    kind: UserDefinedNetwork
    listKind: UserDefinedNetworkList
    plural: userdefinednetworks
    singular: userdefinednetwork
  scope: Namespaced
  versions:
  - name: v1
    schema:
      openAPIV3Schema:
        description: UserDefinedNetwork describe network request for a Namespace.
        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: UserDefinedNetworkSpec defines the desired state of UserDefinedNetworkSpec.
            properties:
              layer2:
                description: Layer2 is the Layer2 topology configuration.
                properties:
                  ipam:
                    description: IPAM section contains IPAM-related configuration
                      for the network.
                    minProperties: 1
                    properties:
                      lifecycle:
                        description: |-
                          Lifecycle controls IP addresses management lifecycle.

                          The only allowed value is Persistent. When set, OVN Kubernetes assigned IP addresses will be persisted in an
                          `ipamclaims.k8s.cni.cncf.io` object. These IP addresses will be reused by other pods if requested.
                          Only supported when mode is `Enabled`.
                        enum:
                        - Persistent
                        type: string
                      mode:
                        description: |-
                          Mode controls how much of the IP configuration will be managed by OVN.
                          `Enabled` means OVN-Kubernetes will apply IP configuration to the SDN infrastructure and it will also assign IPs
                          from the selected subnet to the individual pods.
                          `Disabled` means OVN-Kubernetes will only assign MAC addresses and provide layer 2 communication, letting users
                          configure IP addresses for the pods.
                          `Disabled` is only available for Secondary networks.
                          By disabling IPAM, any Kubernetes features that rely on selecting pods by IP will no longer function
                          (such as network policy, services, etc). Additionally, IP port security will also be disabled for interfaces attached to this network.
                          Defaults to `Enabled`.
                        enum:
                        - Enabled
                        - Disabled
                        type: string
                    type: object
                    x-kubernetes-validations:
                    - message: lifecycle Persistent is only supported when ipam.mode
                        is Enabled
                      rule: '!has(self.lifecycle) || self.lifecycle != ''Persistent''
                        || !has(self.mode) || self.mode == ''Enabled'''
                  joinSubnets:
                    description: |-
                      JoinSubnets are used inside the OVN network topology.

                      Dual-stack clusters may set 2 subnets (one for each IP family), otherwise only 1 subnet is allowed.
                      This field is only allowed for "Primary" network.
                      It is not recommended to set this field without explicit need and understanding of the OVN network topology.
                      When omitted, the platform will choose a reasonable default which is subject to change over time.
                    items:
                      maxLength: 43
                      type: string
                      x-kubernetes-validations:
                      - message: CIDR is invalid
                        rule: isCIDR(self)
                    maxItems: 2
                    minItems: 1
                    type: array
                    x-kubernetes-validations:
                    - message: When 2 CIDRs are set, they must be from different IP
                        families
                      rule: size(self) != 2 || !isCIDR(self[0]) || !isCIDR(self[1])
                        || cidr(self[0]).ip().family() != cidr(self[1]).ip().family()
                  mtu:
                    description: |-
                      MTU is the maximum transmission unit for a network.
                      MTU is optional, if not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.
                    format: int32
                    maximum: 65536
                    minimum: 576
                    type: integer
                  role:
                    description: |-
                      Role describes the network role in the pod.

                      Allowed value is "Secondary".
                      Secondary network is only assigned to pods that use `k8s.v1.cni.cncf.io/networks` annotation to select given network.
                    enum:
                    - Primary
                    - Secondary
                    type: string
                  subnets:
                    description: |-
                      Subnets are used for the pod network across the cluster.
                      Dual-stack clusters may set 2 subnets (one for each IP family), otherwise only 1 subnet is allowed.

                      The format should match standard CIDR notation (for example, "10.128.0.0/16").
                      This field must be omitted if `ipam.mode` is `Disabled`.
                    items:
                      maxLength: 43
                      type: string
                      x-kubernetes-validations:
                      - message: CIDR is invalid
                        rule: isCIDR(self)
                    maxItems: 2
                    minItems: 1
                    type: array
                    x-kubernetes-validations:
                    - message: When 2 CIDRs are set, they must be from different IP
                        families
                      rule: size(self) != 2 || !isCIDR(self[0]) || !isCIDR(self[1])
                        || cidr(self[0]).ip().family() != cidr(self[1]).ip().family()
                required:
                - role
                type: object
                x-kubernetes-validations:
                - message: Subnets is required with ipam.mode is Enabled or unset
                  rule: has(self.ipam) && has(self.ipam.mode) && self.ipam.mode !=
                    'Enabled' || has(self.subnets)
                - message: Subnets must be unset when ipam.mode is Disabled
                  rule: '!has(self.ipam) || !has(self.ipam.mode) || self.ipam.mode
                    != ''Disabled'' || !has(self.subnets)'
                - message: Disabled ipam.mode is only supported for Secondary network
                  rule: '!has(self.ipam) || !has(self.ipam.mode) || self.ipam.mode
                    != ''Disabled'' || self.role == ''Secondary'''
                - message: JoinSubnets is only supported for Primary network
                  rule: '!has(self.joinSubnets) || has(self.role) && self.role ==
                    ''Primary'''
                - message: MTU should be greater than or equal to 1280 when IPv6 subent
                    is used
                  rule: '!has(self.subnets) || !has(self.mtu) || !self.subnets.exists_one(i,
                    isCIDR(i) && cidr(i).ip().family() == 6) || self.mtu >= 1280'
              layer3:
                description: Layer3 is the Layer3 topology configuration.
                properties:
                  joinSubnets:
                    description: |-
                      JoinSubnets are used inside the OVN network topology.

                      Dual-stack clusters may set 2 subnets (one for each IP family), otherwise only 1 subnet is allowed.
                      This field is only allowed for "Primary" network.
                      It is not recommended to set this field without explicit need and understanding of the OVN network topology.
                      When omitted, the platform will choose a reasonable default which is subject to change over time.
                    items:
                      maxLength: 43
                      type: string
                      x-kubernetes-validations:
                      - message: CIDR is invalid
                        rule: isCIDR(self)
                    maxItems: 2
                    minItems: 1
                    type: array
                    x-kubernetes-validations:
                    - message: When 2 CIDRs are set, they must be from different IP
                        families
                      rule: size(self) != 2 || !isCIDR(self[0]) || !isCIDR(self[1])
                        || cidr(self[0]).ip().family() != cidr(self[1]).ip().family()
                  mtu:
                    description: |-
                      MTU is the maximum transmission unit for a network.

                      MTU is optional, if not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.
                    format: int32
                    maximum: 65536
                    minimum: 576
                    type: integer
                  role:
                    description: |-
                      Role describes the network role in the pod.

                      Allowed values are "Primary" and "Secondary".
                      Primary network is automatically assigned to every pod created in the same namespace.
                      Secondary network is only assigned to pods that use `k8s.v1.cni.cncf.io/networks` annotation to select given network.
                    enum:
                    - Primary
                    - Secondary
                    type: string
                  subnets:
                    description: |-
                      Subnets are used for the pod network across the cluster.

                      Dual-stack clusters may set 2 subnets (one for each IP family), otherwise only 1 subnet is allowed.
                      Given subnet is split into smaller subnets for every node.
                    items:
                      properties:
                        cidr:
                          description: CIDR specifies L3Subnet, which is split into
                            smaller subnets for every node.
                          maxLength: 43
                          type: string
                          x-kubernetes-validations:
                          - message: CIDR is invalid
                            rule: isCIDR(self)
                        hostSubnet:
                          description: |-
                            HostSubnet specifies the subnet size for every node.

                            When not set, it will be assigned automatically.
                          format: int32
                          maximum: 127
                          minimum: 1
                          type: integer
                      required:
                      - cidr
                      type: object
                      x-kubernetes-validations:
                      - message: HostSubnet must be smaller than CIDR subnet
                        rule: '!has(self.hostSubnet) || !isCIDR(self.cidr) || self.hostSubnet
                          > cidr(self.cidr).prefixLength()'
                      - message: HostSubnet must < 32 for ipv4 CIDR
                        rule: '!has(self.hostSubnet) || !isCIDR(self.cidr) || (cidr(self.cidr).ip().family()
                          != 4 || self.hostSubnet < 32)'
                    maxItems: 2
                    minItems: 1
                    type: array
                    x-kubernetes-validations:
                    - message: When 2 CIDRs are set, they must be from different IP
                        families
                      rule: size(self) != 2 || !isCIDR(self[0].cidr) || !isCIDR(self[1].cidr)
                        || cidr(self[0].cidr).ip().family() != cidr(self[1].cidr).ip().family()
                required:
                - role
                - subnets
                type: object
                x-kubernetes-validations:
                - message: JoinSubnets is only supported for Primary network
                  rule: '!has(self.joinSubnets) || has(self.role) && self.role ==
                    ''Primary'''
                - message: MTU should be greater than or equal to 1280 when IPv6 subent
                    is used
                  rule: '!has(self.subnets) || !has(self.mtu) || !self.subnets.exists_one(i,
                    isCIDR(i.cidr) && cidr(i.cidr).ip().family() == 6) || self.mtu
                    >= 1280'
              topology:
                description: |-
                  Topology describes network configuration.

                  Allowed values are "Layer3", "Layer2".
                  Layer3 topology creates a layer 2 segment per node, each with a different subnet. Layer 3 routing is used to interconnect node subnets.
                  Layer2 topology creates one logical switch shared by all nodes.
                enum:
                - Layer2
                - Layer3
                type: string
            required:
            - topology
            type: object
            x-kubernetes-validations:
            - message: Spec is immutable
              rule: self == oldSelf
            - message: spec.layer3 is required when topology is Layer3 and forbidden
                otherwise
              rule: 'has(self.topology) && self.topology == ''Layer3'' ? has(self.layer3):
                !has(self.layer3)'
            - message: spec.layer2 is required when topology is Layer2 and forbidden
                otherwise
              rule: 'has(self.topology) && self.topology == ''Layer2'' ? has(self.layer2):
                !has(self.layer2)'
          status:
            description: UserDefinedNetworkStatus contains the observed status of
              the UserDefinedNetwork.
            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
                x-kubernetes-list-map-keys:
                - type
                x-kubernetes-list-type: map
            type: object
        required:
        - spec
        type: object
    served: true
    storage: true
    subresources:
      status: {}
status:
  acceptedNames:
    kind: UserDefinedNetwork
    listKind: UserDefinedNetworkList
    plural: userdefinednetworks
    singular: userdefinednetwork
  conditions:
  - lastTransitionTime: "2025-10-27T11:29:55Z"
    message: no conflicts found
    reason: NoConflicts
    status: "True"
    type: NamesAccepted
  - lastTransitionTime: "2025-10-27T11:29:55Z"
    message: the initial names have been accepted
    reason: InitialNamesAccepted
    status: "True"
    type: Established
  storedVersions:
  - v1
