Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(webhook): initial OpenAPI spec #4874

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,9 @@ jobs:
with:
args: --timeout=30m
version: v1.60

shell: bash
- name: Run Vacuum
run: |
go run github.com/daveshanley/vacuum@latest lint -d api/webhook.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we pin this or use a specific pinned action?

shell: bash
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,12 @@ licensecheck:
exit 1; \
fi

oas-lint:
go run github.com/daveshanley/vacuum@latest lint -d api/webhook.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the pinning comment above.


# 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 @@
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this generated or written from scratch? I don't see us changing the webhook interface a lot, but how do we remember to keep it up to date in that case? Is it a manual operation?

openapi: "3.0.0"
info:
version: 0.14.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the ExternalDNS version? Do we want to add a v in front so that we can more easily find and replace it on release?

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 k8s deployment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extreme nitpick, but for me it's better to always spell it Kubernetes, it is way more accessible to newcomers.

Suggested change
description: Server url for a k8s deployment.
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: |
Failed to provide the list of domains we serve.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, I think. We failed the negotiation at this point.


/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
1 change: 0 additions & 1 deletion provider/webhook/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ func TestAdjustEndpoints(t *testing.T) {
}
j, _ := json.Marshal(endpoints)
w.Write(j)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a mistake?

}))
defer svr.Close()

Expand Down