# Integration Test Scenarios
#
# Schema Summary:
# | Field                                  | Type     | Description                              |
# |----------------------------------------|----------|------------------------------------------|
# | name                                   | string   | Test scenario name                       |
# | config.sources                         | []string | Sources to create: ingress, service      |
# | config.defaultTargets                  | []string | --default-targets flag values            |
# | config.forceDefaultTargets             | bool     | --force-default-targets flag             |
# | config.targetNetFilter                 | []string | --target-net-filter flag values          |
# | config.serviceTypeFilter               | []string | --service-type-filter flag values        |
# | resources                              | []object | K8s resources with optional dependencies |
# | resources[].resource                   | object   | K8s resource (Ingress, Service, etc.)    |
# | resources[].dependencies               | object   | Auto-generated dependent resources       |
# | resources[].dependencies.pods.replicas | int      | Number of pods to generate               |
# | expected                               | []object | Expected endpoints                       |

# TODO:
# 1. Support to Endpoint.ResourceLabelKey
# 2. Support for Endpoint.RefObject
# 3. Support for Endpoint.ProviderSpecific

scenarios:
  - name: headless-service-with-pods
    description: >
      Test that a headless Service with associated Pods
      creates the correct DNS A records for each Pod IP.
    config:
      sources: ["service"]
      targetNetFilter: ["10.0.0.1/32", "10.0.0.2/32"]
      serviceTypeFilter: ["ClusterIP"]
    resources:
      - resource:
          apiVersion: v1
          kind: Service
          metadata:
            name: headless-svc
            namespace: default
            labels:
              app: myapp
            annotations:
              external-dns.alpha.kubernetes.io/hostname: headless.example.com
          spec:
            type: ClusterIP
            clusterIP: None
            selector:
              app: myapp
        dependencies:
          pods:
            replicas: 3
    expected:
      - dnsName: headless.example.com
        targets: ["10.0.0.1", "10.0.0.2"]
        recordType: A
      - dnsName: headless-svc-0.headless.example.com
        targets: ["10.0.0.1"]
        recordType: A
      - dnsName: headless-svc-1.headless.example.com
        targets: ["10.0.0.2"]
        recordType: A

  - name: service-loadbalancer-with-ip
    description: >
      Test that a Service of type LoadBalancer with an assigned IP
      creates the correct DNS A record.
    config:
      sources: ["service"]
    resources:
      - resource:
          apiVersion: v1
          kind: Service
          metadata:
            name: test-service
            namespace: default
            annotations:
              external-dns.alpha.kubernetes.io/hostname: svc.example.com
          spec:
            selector:
              app.kubernetes.io/name: MyApp
            type: LoadBalancer
          status:
            loadBalancer:
              ingress:
                - ip: 1.2.3.4
    expected:
      - dnsName: svc.example.com
        targets: ["1.2.3.4"]
        recordType: A

  - name: known-limitation-cross-source-dedup-not-applied
    description: >
      Documents a known limitation: when multiple ingresses share the same hostname,
      ingressSource.Endpoints() merges their targets via MergeEndpoints() before the
      dedupSource ever sees them. The resulting combined ingress endpoint
      (["1.2.3.4","203.0.113.10"]) has different Targets.String() than the service
      endpoint (["1.2.3.4"]), so the dedupSource keeps both — producing two A records
      for the same hostname. Ideally the service endpoint would be absorbed into the
      ingress one, but that would require cross-source target merging which does not
      exist today. See the "service-and-ingress-same-hostname-and-ip-dedup" scenario
      for a case where deduplication does work correctly.
    config:
      sources: ["service", "ingress"]
    resources:
      - resource:
          apiVersion: v1
          kind: Service
          metadata:
            name: test-service
            namespace: default
            annotations:
              external-dns.alpha.kubernetes.io/hostname: example.local
          spec:
            selector:
              app.kubernetes.io/name: MyApp
            type: LoadBalancer
          status:
            loadBalancer:
              ingress:
                - ip: 1.2.3.4
      - resource:
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            name: test-ingress
            namespace: default
            annotations:
              kubernetes.io/ingress.class: "nginx"
          spec:
            rules:
              - host: example.local
                http:
                  paths:
                    - path: /
                      pathType: Prefix
                      backend:
                        service:
                          name: my-service
                          port:
                            number: 80
          status:
            loadBalancer:
              ingress:
                - ip: 203.0.113.10
      - resource:
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            name: ingress-with-same-host-and-status-as-service
            namespace: kube-system
            annotations:
              kubernetes.io/ingress.class: "nginx"
          spec:
            rules:
              - host: example.local
                http:
                  paths:
                    - path: /
                      pathType: Prefix
                      backend:
                        service:
                          name: my-service
                          port:
                            number: 80
          status:
            loadBalancer:
              ingress:
                - ip: 1.2.3.4
    expected:
      # The ingress source merges all ingresses with the same hostname via MergeEndpoints(),
      # so both ingresses (203.0.113.10 and 1.2.3.4) produce one combined endpoint.
      - dnsName: example.local
        targets: ["1.2.3.4", "203.0.113.10"]
        recordType: A
      # The service source produces a separate endpoint for the same hostname.
      - dnsName: example.local
        targets: ["1.2.3.4"]
        recordType: A

  - name: service-and-ingress-same-hostname-and-ip-dedup
    description: >
      Test that dedupSource correctly removes an exact duplicate endpoint.
      Both the Service and the Ingress resolve example.local to the same IP
      (1.2.3.4), so each source emits an identical endpoint
      (RecordType=A, DNSName=example.local, Targets=["1.2.3.4"]).
      The dedupSource key is RecordType+DNSName+SetIdentifier+Targets.String(),
      which matches, so the second endpoint is dropped and only one A record survives.
    config:
      sources: ["service", "ingress"]
    resources:
      - resource:
          apiVersion: v1
          kind: Service
          metadata:
            name: test-service
            namespace: default
            annotations:
              external-dns.alpha.kubernetes.io/hostname: example.local
          spec:
            selector:
              app.kubernetes.io/name: MyApp
            type: LoadBalancer
          status:
            loadBalancer:
              ingress:
                - ip: 1.2.3.4
      - resource:
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            name: test-ingress
            namespace: default
            annotations:
              kubernetes.io/ingress.class: "nginx"
          spec:
            rules:
              - host: example.local
                http:
                  paths:
                    - path: /
                      pathType: Prefix
                      backend:
                        service:
                          name: my-service
                          port:
                            number: 80
          status:
            loadBalancer:
              ingress:
                - ip: 1.2.3.4
    expected:
      - dnsName: example.local
        targets: ["1.2.3.4"]
        recordType: A
