apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.17.0
  name: dnsconfigs.tailscale.com
spec:
  group: tailscale.com
  names:
    kind: DNSConfig
    listKind: DNSConfigList
    plural: dnsconfigs
    shortNames:
      - dc
    singular: dnsconfig
  scope: Cluster
  versions:
    - additionalPrinterColumns:
        - description: Service IP address of the nameserver
          jsonPath: .status.nameserver.ip
          name: NameserverIP
          type: string
        - jsonPath: .metadata.creationTimestamp
          name: Age
          type: date
      name: v1alpha1
      schema:
        openAPIV3Schema:
          description: |-
            DNSConfig can be deployed to cluster to make a subset of Tailscale MagicDNS
            names resolvable by cluster workloads. Use this if: A) you need to refer to
            tailnet services, exposed to cluster via Tailscale Kubernetes operator egress
            proxies by the MagicDNS names of those tailnet services (usually because the
            services run over HTTPS)
            B) you have exposed a cluster workload to the tailnet using Tailscale Ingress
            and you also want to refer to the workload from within the cluster over the
            Ingress's MagicDNS name (usually because you have some callback component
            that needs to use the same URL as that used by a non-cluster client on
            tailnet).
            When a DNSConfig is applied to a cluster, Tailscale Kubernetes operator will
            deploy a nameserver for ts.net DNS names and automatically populate it with records
            for any Tailscale egress or Ingress proxies deployed to that cluster.
            Currently you must manually update your cluster DNS configuration to add the
            IP address of the deployed nameserver as a ts.net stub nameserver.
            Instructions for how to do it:
            https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configuration-of-stub-domain-and-upstream-nameserver-using-coredns (for CoreDNS),
            https://cloud.google.com/kubernetes-engine/docs/how-to/kube-dns (for kube-dns).
            Tailscale Kubernetes operator will write the address of a Service fronting
            the nameserver to dsnconfig.status.nameserver.ip.
            DNSConfig is a singleton - you must not create more than one.
            NB: if you want cluster workloads to be able to refer to Tailscale Ingress
            using its MagicDNS name, you must also annotate the Ingress resource with
            tailscale.com/experimental-forward-cluster-traffic-via-ingress annotation to
            ensure that the proxy created for the Ingress listens on its Pod IP address.
          type: object
          required:
            - spec
          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: |-
                Spec describes the desired DNS configuration.
                More info:
                https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
              type: object
              required:
                - nameserver
              properties:
                nameserver:
                  description: |-
                    Configuration for a nameserver that can resolve ts.net DNS names
                    associated with in-cluster proxies for Tailscale egress Services and
                    Tailscale Ingresses. The operator will always deploy this nameserver
                    when a DNSConfig is applied.
                  type: object
                  properties:
                    image:
                      description: Nameserver image. Defaults to tailscale/k8s-nameserver:unstable.
                      type: object
                      properties:
                        repo:
                          description: Repo defaults to tailscale/k8s-nameserver.
                          type: string
                        tag:
                          description: Tag defaults to unstable.
                          type: string
                    pod:
                      description: Pod configuration.
                      type: object
                      properties:
                        tolerations:
                          description: If specified, applies tolerations to the pods deployed by the DNSConfig resource.
                          type: array
                          items:
                            description: |-
                              The pod this Toleration is attached to tolerates any taint that matches
                              the triple <key,value,effect> using the matching operator <operator>.
                            type: object
                            properties:
                              effect:
                                description: |-
                                  Effect indicates the taint effect to match. Empty means match all taint effects.
                                  When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
                                type: string
                              key:
                                description: |-
                                  Key is the taint key that the toleration applies to. Empty means match all taint keys.
                                  If the key is empty, operator must be Exists; this combination means to match all values and all keys.
                                type: string
                              operator:
                                description: |-
                                  Operator represents a key's relationship to the value.
                                  Valid operators are Exists and Equal. Defaults to Equal.
                                  Exists is equivalent to wildcard for value, so that a pod can
                                  tolerate all taints of a particular category.
                                type: string
                              tolerationSeconds:
                                description: |-
                                  TolerationSeconds represents the period of time the toleration (which must be
                                  of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,
                                  it is not set, which means tolerate the taint forever (do not evict). Zero and
                                  negative values will be treated as 0 (evict immediately) by the system.
                                type: integer
                                format: int64
                              value:
                                description: |-
                                  Value is the taint value the toleration matches to.
                                  If the operator is Exists, the value should be empty, otherwise just a regular string.
                                type: string
                    replicas:
                      description: Replicas specifies how many Pods to create. Defaults to 1.
                      type: integer
                      format: int32
                      minimum: 0
                    service:
                      description: Service configuration.
                      type: object
                      properties:
                        clusterIP:
                          description: ClusterIP sets the static IP of the service used by the nameserver.
                          type: string
            status:
              description: |-
                Status describes the status of the DNSConfig. This is set
                and managed by the Tailscale operator.
              type: object
              properties:
                conditions:
                  type: array
                  items:
                    description: Condition contains details for one aspect of the current state of this API Resource.
                    type: object
                    required:
                      - lastTransitionTime
                      - message
                      - reason
                      - status
                      - type
                    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.
                        type: string
                        format: date-time
                      message:
                        description: |-
                          message is a human readable message indicating details about the transition.
                          This may be an empty string.
                        type: string
                        maxLength: 32768
                      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.
                        type: integer
                        format: int64
                        minimum: 0
                      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.
                        type: string
                        maxLength: 1024
                        minLength: 1
                        pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
                      status:
                        description: status of the condition, one of True, False, Unknown.
                        type: string
                        enum:
                          - "True"
                          - "False"
                          - Unknown
                      type:
                        description: type of condition in CamelCase or in foo.example.com/CamelCase.
                        type: string
                        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])$
                  x-kubernetes-list-map-keys:
                    - type
                  x-kubernetes-list-type: map
                nameserver:
                  description: Nameserver describes the status of nameserver cluster resources.
                  type: object
                  properties:
                    ip:
                      description: |-
                        IP is the ClusterIP of the Service fronting the deployed ts.net nameserver.
                        Currently, you must manually update your cluster DNS config to add
                        this address as a stub nameserver for ts.net for cluster workloads to be
                        able to resolve MagicDNS names associated with egress or Ingress
                        proxies.
                        The IP address will change if you delete and recreate the DNSConfig.
                      type: string
      served: true
      storage: true
      subresources:
        status: {}
