Skip to content

Commit

Permalink
Merge pull request #4874 from mloiseleur/webhook-openapi
Browse files Browse the repository at this point in the history
feat(webhook): initial OpenAPI spec
  • Loading branch information
k8s-ci-robot authored Dec 1, 2024
2 parents 94f2d20 + 0a1c52b commit eea985f
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 2 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ jobs:
with:
go-version-file: go.mod

- name: Lint
- name: Lint go code
uses: golangci/golangci-lint-action@v6
with:
args: --timeout=30m
version: v1.60

# Run Spectral
- name: Lint OpenAPI spec
uses: stoplightio/spectral-action@2ad0b9302e32a77c1caccf474a9b2191a8060d83 # v0.8.11
with:
file_glob: 'api/*.yaml'
1 change: 1 addition & 0 deletions .spectral.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends: ["spectral:oas"]
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,13 @@ licensecheck:
exit 1; \
fi

# Requires to install spectral. See https://github.com/stoplightio/spectral
oas-lint:
spectral lint api/*.yaml

# Run all the linters
.PHONY: lint
lint: licensecheck go-lint
lint: licensecheck go-lint oas-lint

# generates CRD using controller-gen
.PHONY: crd
Expand Down
265 changes: 265 additions & 0 deletions api/webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
---
openapi: "3.0.0"
info:
version: v0.15.0
title: External DNS Webhook Server
description: >-
Implements the external DNS webhook endpoints.
contact:
url: https://github.com/kubernetes-sigs/external-dns
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
tags:
- name: initialization
description: Endpoints for initial negotiation.
- name: listing
description: Endpoints to get listings of DNS records.
- name: update
description: Endpoints to update DNS records.
servers:
- url: http://localhost:8888
description: Server url for a Kubernetes deployment.
paths:
/:
get:
summary: >-
Initialisation and negotiates headers and returns domain
filter.
description: |
Initialisation and negotiates headers and returns domain
filter.
operationId: negotiate
tags: [initialization]
responses:
'200':
description: |
The list of domains this DNS provider serves.
content:
application/external.dns.webhook+json;version=1:
schema:
$ref: '#/components/schemas/filters'
example:
filters:
- example.com
'500':
description: |
Negociation failed.
/records:
get:
summary: Returns the current records.
description: |
Get the current records from the DNS provider and return them.
operationId: getRecords
tags: [listing]
responses:
'200':
description: |
Provided the list of DNS records successfully.
content:
application/external.dns.webhook+json;version=1:
schema:
$ref: '#/components/schemas/endpoints'
example:
- dnsName: "test.example.com"
recordTTL: 10
recordType: 'A'
targets:
- "1.2.3.4"
'500':
description: |
Failed to provide the list of DNS records.
post:
summary: Applies the changes.
description: |
Set the records in the DNS provider based on those supplied here.
operationId: setRecords
tags: [update]
requestBody:
description: |
This is the list of changes that need to be applied. There are
four lists of endpoints. The `create` and `delete` lists are lists
of records to create and delete respectively. The `updateOld` and
`updateNew` lists are paired. For each entry there's the old version
of the record and a new version of the record.
required: true
content:
application/external.dns.webhook+json;version=1:
schema:
$ref: '#/components/schemas/changes'
example:
create:
- dnsName: "test.example.com"
recordTTL: 10
recordType: 'A'
responses:
'204':
description: |
Changes were accepted.
'500':
description: |
Changes were not accepted.
/adjustendpoints:
post:
summary: Executes the AdjustEndpoints method.
description: |
Adjusts the records in the provider based on those supplied here.
operationId: adjustRecords
tags: [update]
requestBody:
description: |
This is the list of changes to be applied.
required: true
content:
application/external.dns.webhook+json;version=1:
schema:
$ref: '#/components/schemas/endpoints'
example:
- dnsName: "test.example.com"
recordTTL: 10
recordType: 'A'
targets:
- "1.2.3.4"
responses:
'200':
description: |
Adjustments were accepted.
content:
application/external.dns.webhook+json;version=1:
schema:
$ref: '#/components/schemas/endpoints'
example:
- dnsName: "test.example.com"
recordTTL: 0
recordType: 'A'
targets:
- "1.2.3.4"
'500':
description: |
Adjustments were not accepted.
components:
schemas:
filters:
description: |
external-dns will only create DNS records for host names (specified in ingress objects and services with the external-dns annotation) related to zones that match filters. They can set in external-dns deployment manifest.
type: object
properties:
filters:
type: array
items:
type: string
example: "foo.example.com"
example:
- ".example.com"
example:
filters:
- ".example.com"
- ".example.org"

endpoints:
description: |
This is a list of DNS records.
type: array
items:
$ref: '#/components/schemas/endpoint'
example:
- dnsName: foo.example.com
recordType: A
recordTTL: 60

endpoint:
description: |
This is a DNS record.
type: object
properties:
dnsName:
type: string
example: "foo.example.org"
targets:
$ref: '#/components/schemas/targets'
recordType:
type: string
example: "CNAME"
setIdentifier:
type: string
example: "v1"
recordTTL:
type: integer
format: int64
example: 60
labels:
type: object
additionalProperties:
type: string
example: "foo"
example:
foo: bar
providerSpecific:
type: array
items:
$ref: '#/components/schemas/providerSpecificProperty'
example:
- name: foo
value: bar
example:
dnsName: foo.example.com
recordType: A
recordTTL: 60

targets:
description: |
This is the list of targets that this DNS record points to.
So for an A record it will be a list of IP addresses.
type: array
items:
type: string
example: "::1"
example:
- "1.2.3.4"
- "test.example.org"

providerSpecificProperty:
description: |
Allows provider to pass property specific to their implementation.
type: object
properties:
name:
type: string
example: foo
value:
type: string
example: bar
example:
name: foo
value: bar

changes:
description: |
This is the list of changes send by `external-dns` that need to
be applied. There are four lists of endpoints. The `create`
and `delete` lists are lists of records to create and delete
respectively. The `updateOld` and `updateNew` lists are paired.
For each entry there's the old version of the record and a new
version of the record.
type: object
properties:
create:
$ref: '#/components/schemas/endpoints'
updateOld:
$ref: '#/components/schemas/endpoints'
updateNew:
$ref: '#/components/schemas/endpoints'
delete:
$ref: '#/components/schemas/endpoints'
example:
create:
- dnsName: foo.example.com
recordType: A
recordTTL: 60
delete:
- dnsName: foo.example.org
recordType: CNAME
2 changes: 2 additions & 0 deletions docs/tutorials/webhook-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ The following table represents the methods to implement mapped to their HTTP met
| AdjustEndpoints | POST | /adjustendpoints | Provider specific adjustments of records |
| ApplyChanges | POST | /records | Apply record |

OpenAPI spec is [here](../../api/webhook.yaml).

ExternalDNS will also make requests to the `/` endpoint for negotiation and for deserialization of the `DomainFilter`.

The server needs to respond to those requests by reading the `Accept` header and responding with a corresponding `Content-Type` header specifying the supported media type format and version.
Expand Down

0 comments on commit eea985f

Please sign in to comment.