diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 638a80ab4d5f..c4c1c4212bc2 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -3,6 +3,7 @@ on: [push] jobs: build: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@v2 - name: Clean environment and files diff --git a/Gemfile b/Gemfile index 436faed8a584..ad2e57536948 100644 --- a/Gemfile +++ b/Gemfile @@ -3,4 +3,4 @@ gem 'jekyll', '3.9.0' gem 'kramdown-parser-gfm' gem 'jekyll-redirect-from' gem 'redcarpet', '3.5.0' -gem 'rouge', '3.23.0' +gem 'rouge', '3.24.0' diff --git a/Gemfile.lock b/Gemfile.lock index 55ec58de34a2..32ce052e3f54 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GEM ffi (~> 1.0) redcarpet (3.5.0) rexml (3.2.4) - rouge (3.23.0) + rouge (3.24.0) safe_yaml (1.0.5) sass (3.7.4) sass-listen (~> 4.0.0) @@ -66,7 +66,7 @@ DEPENDENCIES jekyll-redirect-from kramdown-parser-gfm redcarpet (= 3.5.0) - rouge (= 3.23.0) + rouge (= 3.24.0) BUNDLED WITH 1.17.3 diff --git a/LICENSE b/LICENSE index 35329e61b946..652e8c97def8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2018 Kong Inc. (https://konghq.com) +Copyright (c) 2015-2020 Kong Inc. (https://konghq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/app/1.1.x/db-less-and-declarative-config.md b/app/1.1.x/db-less-and-declarative-config.md index 09d8ddad4f44..4b2ff9ad9367 100644 --- a/app/1.1.x/db-less-and-declarative-config.md +++ b/app/1.1.x/db-less-and-declarative-config.md @@ -34,7 +34,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is *declarative*, as opposed to an *imperative* style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/1.2.x/db-less-and-declarative-config.md b/app/1.2.x/db-less-and-declarative-config.md index 32860403ab20..48c6d0aed3e5 100644 --- a/app/1.2.x/db-less-and-declarative-config.md +++ b/app/1.2.x/db-less-and-declarative-config.md @@ -33,7 +33,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is _declarative_, as opposed to an _imperative_ style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/1.3.x/db-less-and-declarative-config.md b/app/1.3.x/db-less-and-declarative-config.md index fdfb08458747..f911a8708808 100644 --- a/app/1.3.x/db-less-and-declarative-config.md +++ b/app/1.3.x/db-less-and-declarative-config.md @@ -34,7 +34,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is *declarative*, as opposed to an *imperative* style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/1.4.x/db-less-and-declarative-config.md b/app/1.4.x/db-less-and-declarative-config.md index fdfb08458747..f911a8708808 100644 --- a/app/1.4.x/db-less-and-declarative-config.md +++ b/app/1.4.x/db-less-and-declarative-config.md @@ -34,7 +34,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is *declarative*, as opposed to an *imperative* style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/1.5.x/db-less-and-declarative-config.md b/app/1.5.x/db-less-and-declarative-config.md index 23ad3a9a6236..073d931ee110 100644 --- a/app/1.5.x/db-less-and-declarative-config.md +++ b/app/1.5.x/db-less-and-declarative-config.md @@ -34,7 +34,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is *declarative*, as opposed to an *imperative* style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/2.0.x/db-less-and-declarative-config.md b/app/2.0.x/db-less-and-declarative-config.md index 5d482b195369..f6f51e517e86 100644 --- a/app/2.0.x/db-less-and-declarative-config.md +++ b/app/2.0.x/db-less-and-declarative-config.md @@ -34,7 +34,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is *declarative*, as opposed to an *imperative* style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/2.1.x/clustering.md b/app/2.1.x/clustering.md index c9ff6c6df0c8..27f40ee1744d 100644 --- a/app/2.1.x/clustering.md +++ b/app/2.1.x/clustering.md @@ -78,6 +78,23 @@ This makes Kong clusters **eventually consistent**. [Back to top](#introduction) +### Use read-only replicas when deploying Kong clusters with Postgres + +When using Postgres as the backend storage, you can optionally enable +Kong to serve read queries from a separate database instance. + +One of the common use cases of this feature is to deploy Kong with the +Amazon Aurora service as backend storage. Because Aurora natively supports +read-only instances, enabling the read-only connection support in Kong +greatly reduces the load on the main database instance since read-only +queries are no longer sent to it. + +To learn more about how to configure this feature, refer to the +[Datastore section](/{{page.kong_version}}/configuration/#datastore-section) +of the Configuration reference. + +[Back to top](#introduction) + ## What is being cached? All of the core entities such as Services, Routes, Plugins, Consumers, Credentials are diff --git a/app/2.1.x/db-less-and-declarative-config.md b/app/2.1.x/db-less-and-declarative-config.md index 068f22ae9059..cb03a1d427e5 100644 --- a/app/2.1.x/db-less-and-declarative-config.md +++ b/app/2.1.x/db-less-and-declarative-config.md @@ -34,7 +34,7 @@ may skip this section. The key idea in declarative configuration is, as its name shows, the notion that it is *declarative*, as opposed to an *imperative* style of configuration. "Imperative" means that a configuration is given as a series of -orders: "do this, then to that". "Declative" means that the configuration is +orders: "do this, then to that". "Declarative" means that the configuration is given all at once: "I declare this to be the state of the world". The Kong Admin API is an example of an imperative configuration tool: the diff --git a/app/2.1.x/proxy.md b/app/2.1.x/proxy.md index a38c80537949..d4cd4fac9545 100644 --- a/app/2.1.x/proxy.md +++ b/app/2.1.x/proxy.md @@ -781,16 +781,13 @@ allows routing via SNIs: Incoming requests with a matching hostname set in the TLS connection's SNI extension would be routed to this Route. As mentioned, SNI routing applies not -only to TLS, but also to other protocols carried over TLS - such as HTTPS and -If multiple SNIs are specified in the Route, any of them can match with the incoming request's SNI. -with the incoming request (OR relationship between the names). +only to TLS, but also to other protocols carried over TLS (for example, HTTPS), and +if multiple SNIs are specified in the Route, any of them can match with the +incoming request's SNI (there is an OR relationship between the names). The SNI is indicated at TLS handshake time and cannot be modified after the TLS connection has been established. This means, for example, that multiple requests reusing the same keepalive connection will have the same SNI hostname while performing router match, regardless of the `Host` header. -has been established. This means keepalive connections that send multiple requests -will have the same SNI hostnames while performing router match -(regardless of the `Host` header). Please note that creating a route with mismatched SNI and `Host` header matcher is possible, but generally discouraged. diff --git a/app/2.2.x/admin-api.md b/app/2.2.x/admin-api.md new file mode 100644 index 000000000000..d9f8d6ca6076 --- /dev/null +++ b/app/2.2.x/admin-api.md @@ -0,0 +1,3772 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/blob/master/scripts/autodoc/admin-api/generate.lua +# or its associated files instead. +# +title: Admin API +skip_read_time: true +toc: false + +service_body: | + Attributes | Description + ---:| --- + `name`
*optional* | The Service name. + `retries`
*optional* | The number of retries to execute upon failure to proxy. Default: `5`. + `protocol` | The protocol used to communicate with the upstream. Accepted values are: `"grpc"`, `"grpcs"`, `"http"`, `"https"`, `"tcp"`, `"tls"`, `"udp"`. Default: `"http"`. + `host` | The host of the upstream server. + `port` | The upstream server port. Default: `80`. + `path`
*optional* | The path to be used in requests to the upstream server. + `connect_timeout`
*optional* | The timeout in milliseconds for establishing a connection to the upstream server. Default: `60000`. + `write_timeout`
*optional* | The timeout in milliseconds between two successive write operations for transmitting a request to the upstream server. Default: `60000`. + `read_timeout`
*optional* | The timeout in milliseconds between two successive read operations for transmitting a request to the upstream server. Default: `60000`. + `tags`
*optional* | An optional set of strings associated with the Service for grouping and filtering. + `client_certificate`
*optional* | Certificate to be used as client certificate while TLS handshaking to the upstream server. With form-encoded, the notation is `client_certificate.id=`. With JSON, use "`"client_certificate":{"id":""}`. + `tls_verify`
*optional* | Whether to enable verification of upstream server TLS certificate. If set to `null`, then the Nginx default is respected. + `tls_verify_depth`
*optional* | Maximum depth of chain while verifying Upstream server's TLS certificate. If set to `null`, then the Nginx default is respected. Default: `null`. + `ca_certificates`
*optional* | Array of `CA Certificate` object UUIDs that are used to build the trust store while verifying upstream server's TLS certificate. If set to `null` when Nginx default is respected. If default CA list in Nginx are not specified and TLS verification is enabled, then handshake with upstream server will always fail (because no CA are trusted). With form-encoded, the notation is `ca_certificates[]=4e3ad2e4-0bc4-4638-8e34-c84a417ba39b&ca_certificates[]=51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515`. With JSON, use an Array. + `url`
*shorthand-attribute* | Shorthand attribute to set `protocol`, `host`, `port` and `path` at once. This attribute is write-only (the Admin API never returns the URL). + +service_json: | + { + "id": "9748f662-7711-4a90-8186-dc02f10eb0f5", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"4e3ad2e4-0bc4-4638-8e34-c84a417ba39b"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + } + +service_data: | + "data": [{ + "id": "a5fb8d9b-a99d-40e9-9d35-72d42a62d83a", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + }, { + "id": "fc73f2af-890d-4f9b-8363-af8945001f7f", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/another_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["admin", "high-priority", "critical"], + "client_certificate": {"id":"4506673d-c825-444c-a25b-602e3c2ec16e"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + }], + +route_body: | + Attributes | Description + ---:| --- + `name`
*optional* | The name of the Route. + `protocols` | A list of the protocols this Route should allow. When set to `["https"]`, HTTP requests are answered with a request to upgrade to HTTPS. Default: `["http", "https"]`. + `methods`
*semi-optional* | A list of HTTP methods that match this Route. + `hosts`
*semi-optional* | A list of domain names that match this Route. With form-encoded, the notation is `hosts[]=example.com&hosts[]=foo.test`. With JSON, use an Array. + `paths`
*semi-optional* | A list of paths that match this Route. With form-encoded, the notation is `paths[]=/foo&paths[]=/bar`. With JSON, use an Array. + `headers`
*semi-optional* | One or more lists of values indexed by header name that will cause this Route to match if present in the request. The `Host` header cannot be used with this attribute: hosts should be specified using the `hosts` attribute. + `https_redirect_status_code` | The status code Kong responds with when all properties of a Route match except the protocol i.e. if the protocol of the request is `HTTP` instead of `HTTPS`. `Location` header is injected by Kong if the field is set to 301, 302, 307 or 308. Accepted values are: `426`, `301`, `302`, `307`, `308`. Default: `426`. + `regex_priority`
*optional* | A number used to choose which route resolves a given request when several routes match it using regexes simultaneously. When two routes match the path and have the same `regex_priority`, the older one (lowest `created_at`) is used. Note that the priority for non-regex routes is different (longer non-regex routes are matched before shorter ones). Default: `0`. + `strip_path`
*optional* | When matching a Route via one of the `paths`, strip the matching prefix from the upstream request URL. Default: `true`. + `path_handling`
*optional* | Controls how the Service path, Route path and requested path are combined when sending a request to the upstream. See above for a detailed description of each behavior. Accepted values are: `"v0"`, `"v1"`. Default: `"v0"`. + `preserve_host`
*optional* | When matching a Route via one of the `hosts` domain names, use the request `Host` header in the upstream request headers. If set to `false`, the upstream `Host` header will be that of the Service's `host`. + `request_buffering` | Whether to enable request body buffering or not. With HTTP 1.1, it may make sense to turn this off on services that receive data with chunked transfer encoding. Default: `true`. + `response_buffering` | Whether to enable response body buffering or not. With HTTP 1.1, it may make sense to turn this off on services that send data with chunked transfer encoding. Default: `true`. + `snis`
*semi-optional* | A list of SNIs that match this Route when using stream routing. + `sources`
*semi-optional* | A list of IP sources of incoming connections that match this Route when using stream routing. Each entry is an object with fields "ip" (optionally in CIDR range notation) and/or "port". + `destinations`
*semi-optional* | A list of IP destinations of incoming connections that match this Route when using stream routing. Each entry is an object with fields "ip" (optionally in CIDR range notation) and/or "port". + `tags`
*optional* | An optional set of strings associated with the Route for grouping and filtering. + `service`
*optional* | The Service this Route is associated to. This is where the Route proxies traffic to. With form-encoded, the notation is `service.id=` or `service.name=`. With JSON, use "`"service":{"id":""}` or `"service":{"name":""}`. + +route_json: | + { + "id": "d35165e2-d03e-461a-bdeb-dad0a112abfe", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["http", "https"], + "methods": ["GET", "POST"], + "hosts": ["example.com", "foo.test"], + "paths": ["/foo", "/bar"], + "headers": {"x-another-header":["bla"], "x-my-header":["foo", "bar"]}, + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "tags": ["user-level", "low-priority"], + "service": {"id":"af8330d3-dbdc-48bd-b1be-55b98608834b"} + } + +route_data: | + "data": [{ + "id": "a9daa3ba-8186-4a0d-96e8-00d80ce7240b", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["http", "https"], + "methods": ["GET", "POST"], + "hosts": ["example.com", "foo.test"], + "paths": ["/foo", "/bar"], + "headers": {"x-another-header":["bla"], "x-my-header":["foo", "bar"]}, + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "tags": ["user-level", "low-priority"], + "service": {"id":"127dfc88-ed57-45bf-b77a-a9d3a152ad31"} + }, { + "id": "9aa116fd-ef4a-4efa-89bf-a0b17c4be982", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["tcp", "tls"], + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "snis": ["foo.test", "example.com"], + "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "destinations": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "tags": ["admin", "high-priority", "critical"], + "service": {"id":"ba641b07-e74a-430a-ab46-94b61e5ea66b"} + }], + +consumer_body: | + Attributes | Description + ---:| --- + `username`
*semi-optional* | The unique username of the Consumer. You must send either this field or `custom_id` with the request. + `custom_id`
*semi-optional* | Field for storing an existing unique ID for the Consumer - useful for mapping Kong with users in your existing database. You must send either this field or `username` with the request. + `tags`
*optional* | An optional set of strings associated with the Consumer for grouping and filtering. + +consumer_json: | + { + "id": "ec1a1f6f-2aa4-4e58-93ff-b56368f19b27", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "tags": ["user-level", "low-priority"] + } + +consumer_data: | + "data": [{ + "id": "a4407883-c166-43fd-80ca-3ca035b0cdb7", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "tags": ["user-level", "low-priority"] + }, { + "id": "01c23299-839c-49a5-a6d5-8864c09184af", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "tags": ["admin", "high-priority", "critical"] + }], + +plugin_body: | + Attributes | Description + ---:| --- + `name` | The name of the Plugin that's going to be added. Currently, the Plugin must be installed in every Kong instance separately. + `route`
*optional* | If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the Route being used. Default: `null`.With form-encoded, the notation is `route.id=` or `route.name=`. With JSON, use "`"route":{"id":""}` or `"route":{"name":""}`. + `service`
*optional* | If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched. Default: `null`.With form-encoded, the notation is `service.id=` or `service.name=`. With JSON, use "`"service":{"id":""}` or `"service":{"name":""}`. + `consumer`
*optional* | If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer. Default: `null`.With form-encoded, the notation is `consumer.id=` or `consumer.username=`. With JSON, use "`"consumer":{"id":""}` or `"consumer":{"username":""}`. + `config`
*optional* | The configuration properties for the Plugin which can be found on the plugins documentation page in the [Kong Hub](https://docs.konghq.com/hub/). + `protocols` | A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support `"tcp"` and `"tls"`. Default: `["grpc", "grpcs", "http",`` "https"]`. + `enabled`
*optional* | Whether the plugin is applied. Default: `true`. + `tags`
*optional* | An optional set of strings associated with the Plugin for grouping and filtering. + +plugin_json: | + { + "id": "ce44eef5-41ed-47f6-baab-f725cecf98c7", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"hour":500, "minute":20}, + "protocols": ["http", "https"], + "enabled": true, + "tags": ["user-level", "low-priority"] + } + +plugin_data: | + "data": [{ + "id": "02621eee-8309-4bf6-b36b-a82017a5393e", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"hour":500, "minute":20}, + "protocols": ["http", "https"], + "enabled": true, + "tags": ["user-level", "low-priority"] + }, { + "id": "66c7b5c4-4aaf-4119-af1e-ee3ad75d0af4", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"hour":500, "minute":20}, + "protocols": ["tcp", "tls"], + "enabled": true, + "tags": ["admin", "high-priority", "critical"] + }], + +certificate_body: | + Attributes | Description + ---:| --- + `cert` | PEM-encoded public certificate chain of the SSL key pair. + `key` | PEM-encoded private key of the SSL key pair. + `tags`
*optional* | An optional set of strings associated with the Certificate for grouping and filtering. + `snis`
*shorthand-attribute* | An array of zero or more hostnames to associate with this certificate as SNIs. This is a sugar parameter that will, under the hood, create an SNI object and associate it with this certificate for your convenience. To set this attribute this certificate must have a valid private key associated with it. + +certificate_json: | + { + "id": "7fca84d6-7d37-4a74-a7b0-93e576089a41", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "tags": ["user-level", "low-priority"] + } + +certificate_data: | + "data": [{ + "id": "d044b7d4-3dc2-4bbc-8e9f-6b7a69416df6", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "tags": ["user-level", "low-priority"] + }, { + "id": "a9b2107f-a214-47b3-add4-46b942187924", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "tags": ["admin", "high-priority", "critical"] + }], + +ca_certificate_body: | + Attributes | Description + ---:| --- + `cert` | PEM-encoded public certificate of the CA. + `cert_digest`
*optional* | SHA256 hex digest of the public certificate. + `tags`
*optional* | An optional set of strings associated with the Certificate for grouping and filtering. + +ca_certificate_json: | + { + "id": "04fbeacf-a9f1-4a5d-ae4a-b0407445db3f", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["user-level", "low-priority"] + } + +ca_certificate_data: | + "data": [{ + "id": "43429efd-b3a5-4048-94cb-5cc4029909bb", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["user-level", "low-priority"] + }, { + "id": "d26761d5-83a4-4f24-ac6c-cff276f2b79c", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["admin", "high-priority", "critical"] + }], + +sni_body: | + Attributes | Description + ---:| --- + `name` | The SNI name to associate with the given certificate. + `tags`
*optional* | An optional set of strings associated with the SNIs for grouping and filtering. + `certificate` | The id (a UUID) of the certificate with which to associate the SNI hostname. The Certificate must have a valid private key associated with it to be used by the SNI object. With form-encoded, the notation is `certificate.id=`. With JSON, use "`"certificate":{"id":""}`. + +sni_json: | + { + "id": "91020192-062d-416f-a275-9addeeaffaf2", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["user-level", "low-priority"], + "certificate": {"id":"a2e013e8-7623-4494-a347-6d29108ff68b"} + } + +sni_data: | + "data": [{ + "id": "147f5ef0-1ed6-4711-b77f-489262f8bff7", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["user-level", "low-priority"], + "certificate": {"id":"a3ad71a8-6685-4b03-a101-980a953544f6"} + }, { + "id": "b87eb55d-69a1-41d2-8653-8d706eecefc0", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["admin", "high-priority", "critical"], + "certificate": {"id":"4e8d95d4-40f2-4818-adcb-30e00c349618"} + }], + +upstream_body: | + Attributes | Description + ---:| --- + `name` | This is a hostname, which must be equal to the `host` of a Service. + `algorithm`
*optional* | Which load balancing algorithm to use. Accepted values are: `"consistent-hashing"`, `"least-connections"`, `"round-robin"`. Default: `"round-robin"`. + `hash_on`
*optional* | What to use as hashing input. Using `none` results in a weighted-round-robin scheme with no hashing. Accepted values are: `"none"`, `"consumer"`, `"ip"`, `"header"`, `"cookie"`. Default: `"none"`. + `hash_fallback`
*optional* | What to use as hashing input if the primary `hash_on` does not return a hash (eg. header is missing, or no Consumer identified). Not available if `hash_on` is set to `cookie`. Accepted values are: `"none"`, `"consumer"`, `"ip"`, `"header"`, `"cookie"`. Default: `"none"`. + `hash_on_header`
*semi-optional* | The header name to take the value from as hash input. Only required when `hash_on` is set to `header`. + `hash_fallback_header`
*semi-optional* | The header name to take the value from as hash input. Only required when `hash_fallback` is set to `header`. + `hash_on_cookie`
*semi-optional* | The cookie name to take the value from as hash input. Only required when `hash_on` or `hash_fallback` is set to `cookie`. If the specified cookie is not in the request, Kong will generate a value and set the cookie in the response. + `hash_on_cookie_path`
*semi-optional* | The cookie path to set in the response headers. Only required when `hash_on` or `hash_fallback` is set to `cookie`. Default: `"/"`. + `slots`
*optional* | The number of slots in the loadbalancer algorithm (`10`-`65536`). Default: `10000`. + `healthchecks.active.``https_verify_certificate`
*optional* | Whether to check the validity of the SSL certificate of the remote host when performing active health checks using HTTPS. Default: `true`. + `healthchecks.active.``unhealthy.http_statuses`
*optional* | An array of HTTP statuses to consider a failure, indicating unhealthiness, when returned by a probe in active health checks. Default: `[429, 404, 500, 501, 502, 503,`` 504, 505]`. With form-encoded, the notation is `http_statuses[]=429&http_statuses[]=404`. With JSON, use an Array. + `healthchecks.active.``unhealthy.tcp_failures`
*optional* | Number of TCP failures in active probes to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.timeouts`
*optional* | Number of timeouts in active probes to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.http_failures`
*optional* | Number of HTTP failures in active probes (as defined by `healthchecks.active.unhealthy.http_statuses`) to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.interval`
*optional* | Interval between active health checks for unhealthy targets (in seconds). A value of zero indicates that active probes for unhealthy targets should not be performed. Default: `0`. + `healthchecks.active.``http_path`
*optional* | Path to use in GET HTTP request to run as a probe on active health checks. Default: `"/"`. + `healthchecks.active.``timeout`
*optional* | Socket timeout for active health checks (in seconds). Default: `1`. + `healthchecks.active.``healthy.http_statuses`
*optional* | An array of HTTP statuses to consider a success, indicating healthiness, when returned by a probe in active health checks. Default: `[200, 302]`. With form-encoded, the notation is `http_statuses[]=200&http_statuses[]=302`. With JSON, use an Array. + `healthchecks.active.``healthy.interval`
*optional* | Interval between active health checks for healthy targets (in seconds). A value of zero indicates that active probes for healthy targets should not be performed. Default: `0`. + `healthchecks.active.``healthy.successes`
*optional* | Number of successes in active probes (as defined by `healthchecks.active.healthy.http_statuses`) to consider a target healthy. Default: `0`. + `healthchecks.active.``https_sni`
*optional* | The hostname to use as an SNI (Server Name Identification) when performing active health checks using HTTPS. This is particularly useful when Targets are configured using IPs, so that the target host's certificate can be verified with the proper SNI. + `healthchecks.active.``concurrency`
*optional* | Number of targets to check concurrently in active health checks. Default: `10`. + `healthchecks.active.type`
*optional* | Whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection. Accepted values are: `"tcp"`, `"http"`, `"https"`, `"grpc"`, `"grpcs"`. Default: `"http"`. + `healthchecks.passive.``unhealthy.http_failures`
*optional* | Number of HTTP failures in proxied traffic (as defined by `healthchecks.passive.unhealthy.http_statuses`) to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``unhealthy.http_statuses`
*optional* | An array of HTTP statuses which represent unhealthiness when produced by proxied traffic, as observed by passive health checks. Default: `[429, 500, 503]`. With form-encoded, the notation is `http_statuses[]=429&http_statuses[]=500`. With JSON, use an Array. + `healthchecks.passive.``unhealthy.tcp_failures`
*optional* | Number of TCP failures in proxied traffic to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``unhealthy.timeouts`
*optional* | Number of timeouts in proxied traffic to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``type`
*optional* | Whether to perform passive health checks interpreting HTTP/HTTPS statuses, or just check for TCP connection success. In passive checks, `http` and `https` options are equivalent. Accepted values are: `"tcp"`, `"http"`, `"https"`, `"grpc"`, `"grpcs"`. Default: `"http"`. + `healthchecks.passive.``healthy.successes`
*optional* | Number of successes in proxied traffic (as defined by `healthchecks.passive.healthy.http_statuses`) to consider a target healthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``healthy.http_statuses`
*optional* | An array of HTTP statuses which represent healthiness when produced by proxied traffic, as observed by passive health checks. Default: `[200, 201, 202, 203, 204, 205,`` 206, 207, 208, 226, 300, 301,`` 302, 303, 304, 305, 306, 307,`` 308]`. With form-encoded, the notation is `http_statuses[]=200&http_statuses[]=201`. With JSON, use an Array. + `healthchecks.threshold`
*optional* | The minimum percentage of the upstream's targets' weight that must be available for the whole upstream to be considered healthy. Default: `0`. + `tags`
*optional* | An optional set of strings associated with the Upstream for grouping and filtering. + `host_header`
*optional* | The hostname to be used as `Host` header when proxying requests through Kong. + `client_certificate`
*optional* | If set, the certificate to be used as client certificate while TLS handshaking to the upstream server.With form-encoded, the notation is `client_certificate.id=`. With JSON, use "`"client_certificate":{"id":""}`. + +upstream_json: | + { + "id": "58c8ccbb-eafb-4566-991f-2ed4f678fa70", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "https_verify_certificate": true, + "unhealthy": { + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "tcp_failures": 0, + "timeouts": 0, + "http_failures": 0, + "interval": 0 + }, + "http_path": "/", + "timeout": 1, + "healthy": { + "http_statuses": [200, 302], + "interval": 0, + "successes": 0 + }, + "https_sni": "example.com", + "concurrency": 10, + "type": "http" + }, + "passive": { + "unhealthy": { + "http_failures": 0, + "http_statuses": [429, 500, 503], + "tcp_failures": 0, + "timeouts": 0 + }, + "type": "http", + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + } + }, + "threshold": 0 + }, + "tags": ["user-level", "low-priority"], + "host_header": "example.com", + "client_certificate": {"id":"ea29aaa3-3b2d-488c-b90c-56df8e0dd8c6"} + } + +upstream_data: | + "data": [{ + "id": "4fe14415-73d5-4f00-9fbc-c72a0fccfcb2", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "https_verify_certificate": true, + "unhealthy": { + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "tcp_failures": 0, + "timeouts": 0, + "http_failures": 0, + "interval": 0 + }, + "http_path": "/", + "timeout": 1, + "healthy": { + "http_statuses": [200, 302], + "interval": 0, + "successes": 0 + }, + "https_sni": "example.com", + "concurrency": 10, + "type": "http" + }, + "passive": { + "unhealthy": { + "http_failures": 0, + "http_statuses": [429, 500, 503], + "tcp_failures": 0, + "timeouts": 0 + }, + "type": "http", + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + } + }, + "threshold": 0 + }, + "tags": ["user-level", "low-priority"], + "host_header": "example.com", + "client_certificate": {"id":"a3395f66-2af6-4c79-bea2-1b6933764f80"} + }, { + "id": "885a0392-ef1b-4de3-aacf-af3f1697ce2c", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "https_verify_certificate": true, + "unhealthy": { + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "tcp_failures": 0, + "timeouts": 0, + "http_failures": 0, + "interval": 0 + }, + "http_path": "/", + "timeout": 1, + "healthy": { + "http_statuses": [200, 302], + "interval": 0, + "successes": 0 + }, + "https_sni": "example.com", + "concurrency": 10, + "type": "http" + }, + "passive": { + "unhealthy": { + "http_failures": 0, + "http_statuses": [429, 500, 503], + "tcp_failures": 0, + "timeouts": 0 + }, + "type": "http", + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + } + }, + "threshold": 0 + }, + "tags": ["admin", "high-priority", "critical"], + "host_header": "example.com", + "client_certificate": {"id":"f5a9c0ca-bdbb-490f-8928-2ca95836239a"} + }], + +target_body: | + Attributes | Description + ---:| --- + `target` | The target address (ip or hostname) and port. If the hostname resolves to an SRV record, the `port` value will be overridden by the value from the DNS record. + `weight`
*optional* | The weight this target gets within the upstream loadbalancer (`0`-`65535`). If the hostname resolves to an SRV record, the `weight` value will be overridden by the value from the DNS record. Default: `100`. + `tags`
*optional* | An optional set of strings associated with the Target for grouping and filtering. + +target_json: | + { + "id": "173a6cee-90d1-40a7-89cf-0329eca780a6", + "created_at": 1422386534, + "upstream": {"id":"bdab0e47-4e37-4f0b-8fd0-87d95cc4addc"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["user-level", "low-priority"] + } + +target_data: | + "data": [{ + "id": "f00c6da4-3679-4b44-b9fb-36a19bd3ae83", + "created_at": 1422386534, + "upstream": {"id":"0c61e164-6171-4837-8836-8f5298726d53"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["user-level", "low-priority"] + }, { + "id": "5027BBC1-508C-41F8-87F2-AB1801E9D5C3", + "created_at": 1422386534, + "upstream": {"id":"68FDB05B-7B08-47E9-9727-AF7F897CFF1A"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["admin", "high-priority", "critical"] + }], + + +--- + + + +Kong comes with an **internal** RESTful Admin API for administration purposes. +Requests to the Admin API can be sent to any node in the cluster, and Kong will +keep the configuration consistent across all nodes. + +- `8001` is the default port on which the Admin API listens. +- `8444` is the default port for HTTPS traffic to the Admin API. + +This API is designed for internal use and provides full control over Kong, so +care should be taken when setting up Kong environments to avoid undue public +exposure of this API. See [this document][secure-admin-api] for a discussion +of methods to secure the Admin API. + +## Supported Content Types + +The Admin API accepts 3 content types on every endpoint: + +- **application/json** + +Handy for complex bodies (ex: complex plugin configuration), in that case simply send +a JSON representation of the data you want to send. Example: + +```json +{ + "config": { + "limit": 10, + "period": "seconds" + } +} +``` + +An example adding a Route to a Service named `test-service`: + +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -H "Content-Type: application/json" \ + -d '{"name": "test-route", "paths": [ "/path/one", "/path/two" ]}' +``` + +- **application/x-www-form-urlencoded** + +Simple enough for basic request bodies, you will probably use it most of the time. +Note that when sending nested values, Kong expects nested objects to be referenced +with dotted keys. Example: + +``` +config.limit=10&config.period=seconds +``` + +When specifying arrays, send the values in order, or use square brackets (numbering +inside the brackets is optional but if provided it must be 1-indexed, and +consecutive). An example Route added to a Service named `test-service`: + +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -d "name=test-route" \ + -d "paths[1]=/path/one" \ + -d "paths[2]=/path/two" +``` + +The following two examples are identical to the one above, but less explicit: +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -d "name=test-route" \ + -d "paths[]=/path/one" \ + -d "paths[]=/path/two" + +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -d "name=test-route" \ + -d "paths=/path/one" \ + -d "paths=/path/two" +``` + + +- **multipart/form-data** + +Similar to URL-encoded, this content type uses dotted keys to reference nested +objects. Here is an example of sending a Lua file to the pre-function Kong plugin: + +``` +curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ + -F "name=pre-function" \ + -F "config.access=@custom-auth.lua" +``` + +When specifying arrays for this content-type, the array indices must be specified. +An example Route added to a Service named `test-service`: + +``` +curl -i -X POST http://localhost:8001/services/test-service/routes \ + -F "name=test-route" \ + -F "paths[1]=/path/one" \ + -F "paths[2]=/path/two" +``` + +--- + +## Information Routes + + + +### Retrieve Node Information + +Retrieve generic details about a node. + +
/
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "hostname": "", + "node_id": "6a72192c-a3a1-4c8d-95c6-efabae9fb969", + "lua_version": "LuaJIT 2.1.0-beta3", + "plugins": { + "available_on_server": [ + ... + ], + "enabled_in_cluster": [ + ... + ] + }, + "configuration" : { + ... + }, + "tagline": "Welcome to Kong", + "version": "0.14.0" +} +``` + +* `node_id`: A UUID representing the running Kong node. This UUID + is randomly generated when Kong starts, so the node will have a + different `node_id` each time it is restarted. +* `available_on_server`: Names of plugins that are installed on the node. +* `enabled_in_cluster`: Names of plugins that are enabled/configured. + That is, the plugins configurations currently in the datastore shared + by all Kong nodes. + + +--- + +### List Available Endpoints + +List all available endpoints provided by the Admin API. + +
/endpoints
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + "/", + "/acls", + "/acls/{acls}", + "/acls/{acls}/consumer", + "/basic-auths", + "/basic-auths/{basicauth_credentials}", + "/basic-auths/{basicauth_credentials}/consumer", + "/ca_certificates", + "/ca_certificates/{ca_certificates}", + "/cache", + "/cache/{key}", + "..." + ] +} +``` + + +--- + +### Validate A Configuration against A Schema + +Check validity of a configuration against its entity schema. +This allows you to test your input before submitting a request +to the entity endpoints of the Admin API. + +Note that this only performs the schema validation checks, +checking that the input configuration is well-formed. +A requests to the entity endpoint using the given configuration +may still fail due to other reasons, such as invalid foreign +key relationships or uniqueness check failures against the +contents of the data store. + + +
/schemas/{entity}/validate
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "message": "schema validation successful" +} +``` + + +--- + +### Retrieve Entity Schema + +Retrieve the schema of an entity. This is useful to +understand what fields an entity accepts, and can be used for building +third-party integrations to the Kong. + + +
/schemas/{entity name}
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "fields": [ + { + "id": { + "auto": true, + "type": "string", + "uuid": true + } + }, + { + "created_at": { + "auto": true, + "timestamp": true, + "type": "integer" + } + }, + ... + ] +} +``` + + +--- + +### Retrieve Plugin Schema + +Retrieve the schema of a plugin's configuration. This is useful to +understand what fields a plugin accepts, and can be used for building +third-party integrations to the Kong's plugin system. + + +
/schemas/plugins/{plugin name}
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "fields": { + "hide_credentials": { + "default": false, + "type": "boolean" + }, + "key_names": { + "default": "function", + "required": true, + "type": "array" + } + } +} +``` + + +--- + +## Health Routes + + + +### Retrieve Node Status + +Retrieve usage information about a node, with some basic information +about the connections being processed by the underlying nginx process, +the status of the database connection, and node's memory usage. + +If you want to monitor the Kong process, since Kong is built on top +of nginx, every existing nginx monitoring tool or agent can be used. + + +
/status
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "database": { + "reachable": true + }, + "memory": { + "workers_lua_vms": [{ + "http_allocated_gc": "0.02 MiB", + "pid": 18477 + }, { + "http_allocated_gc": "0.02 MiB", + "pid": 18478 + }], + "lua_shared_dicts": { + "kong": { + "allocated_slabs": "0.04 MiB", + "capacity": "5.00 MiB" + }, + "kong_db_cache": { + "allocated_slabs": "0.80 MiB", + "capacity": "128.00 MiB" + }, + } + }, + "server": { + "total_requests": 3, + "connections_active": 1, + "connections_accepted": 1, + "connections_handled": 1, + "connections_reading": 0, + "connections_writing": 1, + "connections_waiting": 0 + } +} +``` + +* `memory`: Metrics about the memory usage. + * `workers_lua_vms`: An array with all workers of the Kong node, where each + entry contains: + * `http_allocated_gc`: HTTP submodule's Lua virtual machine's memory + usage information, as reported by `collectgarbage("count")`, for every + active worker, i.e. a worker that received a proxy call in the last 10 + seconds. + * `pid`: worker's process identification number. + * `lua_shared_dicts`: An array of information about dictionaries that are + shared with all workers in a Kong node, where each array node contains how + much memory is dedicated for the specific shared dictionary (`capacity`) + and how much of said memory is in use (`allocated_slabs`). + These shared dictionaries have least recent used (LRU) eviction + capabilities, so a full dictionary, where `allocated_slabs == capacity`, + will work properly. However for some dictionaries, e.g. cache HIT/MISS + shared dictionaries, increasing their size can be beneficial for the + overall performance of a Kong node. + * The memory usage unit and precision can be changed using the querystring + arguments `unit` and `scale`: + * `unit`: one of `b/B`, `k/K`, `m/M`, `g/G`, which will return results + in bytes, kibibytes, mebibytes, or gibibytes, respectively. When + "bytes" are requested, the memory values in the response will have a + number type instead of string. Defaults to `m`. + * `scale`: the number of digits to the right of the decimal points when + values are given in human-readable memory strings (unit other than + "bytes"). Defaults to `2`. + You can get the shared dictionaries memory usage in kibibytes with 4 + digits of precision by doing: `GET /status?unit=k&scale=4` +* `server`: Metrics about the nginx HTTP/S server. + * `total_requests`: The total number of client requests. + * `connections_active`: The current number of active client + connections including Waiting connections. + * `connections_accepted`: The total number of accepted client + connections. + * `connections_handled`: The total number of handled connections. + Generally, the parameter value is the same as accepts unless + some resource limits have been reached. + * `connections_reading`: The current number of connections + where Kong is reading the request header. + * `connections_writing`: The current number of connections + where nginx is writing the response back to the client. + * `connections_waiting`: The current number of idle client + connections waiting for a request. +* `database`: Metrics about the database. + * `reachable`: A boolean value reflecting the state of the + database connection. Please note that this flag **does not** + reflect the health of the database itself. + + +--- + +## Tags + +Tags are strings associated to entities in Kong. Each tag must be composed of one or more +alphanumeric characters, `_`, `-`, `.` or `~`. + +Most core entities can be *tagged* via their `tags` attribute, upon creation or edition. + +Tags can be used to filter core entities as well, via the `?tags` querystring parameter. + +For example: if you normally get a list of all the Services by doing: + +``` +GET /services +``` + +You can get the list of all the Services tagged `example` by doing: + +``` +GET /services?tags=example +``` + +Similarly, if you want to filter Services so that you only get the ones tagged `example` *and* +`admin`, you can do that like so: + +``` +GET /services?tags=example,admin +``` + +Finally, if you wanted to filter the Services tagged `example` *or* `admin`, you could use: + +``` +GET /services?tags=example/admin +``` + +Some notes: + +* A maximum of 5 tags can be queried simultaneously in a single request with `,` or `/` +* Mixing operators is not supported: if you try to mix `,` with `/` in the same querystring, + you will receive an error. +* You may need to quote and/or escape some characters when using them from the + command line. +* Filtering by `tags` is not supported in foreign key relationship endpoints. For example, + the `tags` parameter will be ignored in a request such as `GET /services/foo/routes?tags=a,b` +* `offset` parameters are not guaranteed to work if the `tags` parameter is altered or removed + + +### List All Tags + +Returns a paginated list of all the tags in the system. + +The list of entities will not be restricted to a single entity type: all the +entities tagged with tags will be present on this list. + +If an entity is tagged with more than one tag, the `entity_id` for that entity +will appear more than once in the resulting list. Similarly, if several entities +have been tagged with the same tag, the tag will appear in several items of this list. + + +
/tags
+ +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "data": [ + { "entity_name": "services", + "entity_id": "acf60b10-125c-4c1a-bffe-6ed55daefba4", + "tag": "s1", + }, + { "entity_name": "services", + "entity_id": "acf60b10-125c-4c1a-bffe-6ed55daefba4", + "tag": "s2", + }, + { "entity_name": "routes", + "entity_id": "60631e85-ba6d-4c59-bd28-e36dd90f6000", + "tag": "s1", + }, + ... + ], + "offset": "c47139f3-d780-483d-8a97-17e9adc5a7ab", + "next": "/tags?offset=c47139f3-d780-483d-8a97-17e9adc5a7ab", + } +} +``` + + +--- + +### List Entity Ids by Tag + +Returns the entities that have been tagged with the specified tag. + +The list of entities will not be restricted to a single entity type: all the +entities tagged with tags will be present on this list. + + +
/tags/{tags}
+ +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "data": [ + { "entity_name": "services", + "entity_id": "c87440e1-0496-420b-b06f-dac59544bb6c", + "tag": "example", + }, + { "entity_name": "routes", + "entity_id": "8a99e4b1-d268-446b-ab8b-cd25cff129b1", + "tag": "example", + }, + ... + ], + "offset": "1fb491c4-f4a7-4bca-aeba-7f3bcee4d2f9", + "next": "/tags/example?offset=1fb491c4-f4a7-4bca-aeba-7f3bcee4d2f9", + } +} +``` + + +--- + +## Service Object + +Service entities, as the name implies, are abstractions of each of your own +upstream services. Examples of Services would be a data transformation +microservice, a billing API, etc. + +The main attribute of a Service is its URL (where Kong should proxy traffic +to), which can be set as a single string or by specifying its `protocol`, +`host`, `port` and `path` individually. + +Services are associated to Routes (a Service can have many Routes associated +with it). Routes are entry-points in Kong and define rules to match client +requests. Once a Route is matched, Kong proxies the request to its associated +Service. See the [Proxy Reference][proxy-reference] for a detailed explanation +of how Kong proxies traffic. + +Services can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.service_json }} +``` + +### Add Service + +##### Create Service + +
/services
+ + +##### Create Service Associated to a Specific Certificate + +
/certificates/{certificate name or id}/services
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate that should be associated to the newly-created Service. + + +#### Request Body + +{{ page.service_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.service_json }} +``` + + +--- + +### List Services + +##### List All Services + +
/services
+ + +##### List Services Associated to a Specific Certificate + +
/certificates/{certificate name or id}/services
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate whose Services are to be retrieved. When using this endpoint, only Services associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.service_data }} + "next": "http://localhost:8001/services?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Service + +##### Retrieve Service + +
/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. + + +##### Retrieve Service Associated to a Specific Certificate + +
/certificates/{certificate id}/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. + + +##### Retrieve Service Associated to a Specific Route + +
/routes/{route name or id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route associated to the Service to be retrieved. + + +##### Retrieve Service Associated to a Specific Plugin + +
/plugins/{plugin id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Service to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.service_json }} +``` + + +--- + +### Update Service + +##### Update Service + +
/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to update. + + +##### Update Service Associated to a Specific Certificate + +
/certificates/{certificate id}/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to update. +`service name or id`
**required** | The unique identifier **or** the name of the Service to update. + + +##### Update Service Associated to a Specific Route + +
/routes/{route name or id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route associated to the Service to be updated. + + +##### Update Service Associated to a Specific Plugin + +
/plugins/{plugin id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Service to be updated. + + +#### Request Body + +{{ page.service_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.service_json }} +``` + + +--- + +### Update Or Create Service + +##### Create Or Update Service + +
/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to create or update. + + +##### Create Or Update Service Associated to a Specific Certificate + +
/certificates/{certificate id}/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to create or update. +`service name or id`
**required** | The unique identifier **or** the name of the Service to create or update. + + +##### Create Or Update Service Associated to a Specific Route + +
/routes/{route name or id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route associated to the Service to be created or updated. + + +##### Create Or Update Service Associated to a Specific Plugin + +
/plugins/{plugin id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Service to be created or updated. + + +#### Request Body + +{{ page.service_body }} + + +Inserts (or replaces) the Service under the requested resource with the +definition specified in the body. The Service will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Service being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Service without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Service + +##### Delete Service + +
/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to delete. + + +##### Delete Service Associated to a Specific Certificate + +
/certificates/{certificate id}/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to delete. +`service name or id`
**required** | The unique identifier **or** the name of the Service to delete. + + +##### Delete Service Associated to a Specific Route + +
/routes/{route name or id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route associated to the Service to be deleted. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Route Object + +Route entities define rules to match client requests. Each Route is +associated with a Service, and a Service may have multiple Routes associated to +it. Every request matching a given Route will be proxied to its associated +Service. + +The combination of Routes and Services (and the separation of concerns between +them) offers a powerful routing mechanism with which it is possible to define +fine-grained entry-points in Kong leading to different upstream services of +your infrastructure. + +You need at least one matching rule that applies to the protocol being matched +by the Route. Depending on the protocols configured to be matched by the Route +(as defined with the `protocols` field), this means that at least one of the +following attributes must be set: + +* For `http`, at least one of `methods`, `hosts`, `headers` or `paths`; +* For `https`, at least one of `methods`, `hosts`, `headers`, `paths` or `snis`; +* For `tcp`, at least one of `sources` or `destinations`; +* For `tls`, at least one of `sources`, `destinations` or `snis`; +* For `grpc`, at least one of `hosts`, `headers` or `paths`; +* For `grpcs`, at least one of `hosts`, `headers`, `paths` or `snis`. + +#### Path handling algorithms + +`"v0"` is the behavior used in Kong 0.x and 2.x. It treats `service.path`, `route.path` and request path as +*segments* of a URL. It will always join them via slashes. Given a service path `/s`, route path `/r` +and request path `/re`, the concatenated path will be `/s/re`. If the resulting path is a single slash, +no further transformation is done to it. If it's longer, then the trailing slash is removed. + +`"v1"` is the behavior used in Kong 1.x. It treats `service.path` as a *prefix*, and ignores the initial +slashes of the request and route paths. Given service path `/s`, route path `/r` and request path `/re`, +the concatenated path will be `/sre`. + +Both versions of the algorithm detect "double slashes" when combining paths, replacing them by single +slashes. + +In the following table, `s` is the Service and `r` is the Route. + +| `s.path` | `r.path` | `r.strip_path` | `r.path_handling` | request path | proxied path | +|----------|----------|----------------|-------------------|--------------|---------------| +| `/s` | `/fv0` | `false` | `v0` | `/fv0req` | `/s/fv0req` | +| `/s` | `/fv1` | `false` | `v1` | `/fv1req` | `/sfv1req` | +| `/s` | `/tv0` | `true` | `v0` | `/tv0req` | `/s/req` | +| `/s` | `/tv1` | `true` | `v1` | `/tv1req` | `/sreq` | +| `/s` | `/fv0/` | `false` | `v0` | `/fv0/req` | `/s/fv0/req` | +| `/s` | `/fv1/` | `false` | `v1` | `/fv1/req` | `/sfv1/req` | +| `/s` | `/tv0/` | `true` | `v0` | `/tv0/req` | `/s/req` | +| `/s` | `/tv1/` | `true` | `v1` | `/tv1/req` | `/sreq` | + + +Routes can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.route_json }} +``` + +### Add Route + +##### Create Route + +
/routes
+ + +##### Create Route Associated to a Specific Service + +
/services/{service name or id}/routes
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier or the `name` attribute of the Service that should be associated to the newly-created Route. + + +#### Request Body + +{{ page.route_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.route_json }} +``` + + +--- + +### List Routes + +##### List All Routes + +
/routes
+ + +##### List Routes Associated to a Specific Service + +
/services/{service name or id}/routes
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier or the `name` attribute of the Service whose Routes are to be retrieved. When using this endpoint, only Routes associated to the specified Service will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.route_data }} + "next": "http://localhost:8001/routes?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Route + +##### Retrieve Route + +
/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to retrieve. + + +##### Retrieve Route Associated to a Specific Service + +
/services/{service name or id}/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. +`route name or id`
**required** | The unique identifier **or** the name of the Route to retrieve. + + +##### Retrieve Route Associated to a Specific Plugin + +
/plugins/{plugin id}/route
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Route to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.route_json }} +``` + + +--- + +### Update Route + +##### Update Route + +
/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to update. + + +##### Update Route Associated to a Specific Service + +
/services/{service name or id}/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to update. +`route name or id`
**required** | The unique identifier **or** the name of the Route to update. + + +##### Update Route Associated to a Specific Plugin + +
/plugins/{plugin id}/route
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Route to be updated. + + +#### Request Body + +{{ page.route_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.route_json }} +``` + + +--- + +### Update Or Create Route + +##### Create Or Update Route + +
/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to create or update. + + +##### Create Or Update Route Associated to a Specific Service + +
/services/{service name or id}/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to create or update. +`route name or id`
**required** | The unique identifier **or** the name of the Route to create or update. + + +##### Create Or Update Route Associated to a Specific Plugin + +
/plugins/{plugin id}/route
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Route to be created or updated. + + +#### Request Body + +{{ page.route_body }} + + +Inserts (or replaces) the Route under the requested resource with the +definition specified in the body. The Route will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Route being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Route without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Route + +##### Delete Route + +
/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to delete. + + +##### Delete Route Associated to a Specific Service + +
/services/{service name or id}/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to delete. +`route name or id`
**required** | The unique identifier **or** the name of the Route to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Consumer Object + +The Consumer object represents a consumer - or a user - of a Service. You can +either rely on Kong as the primary datastore, or you can map the consumer list +with your database to keep consistency between Kong and your existing primary +datastore. + +Consumers can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.consumer_json }} +``` + +### Add Consumer + +##### Create Consumer + +
/consumers
+ + +#### Request Body + +{{ page.consumer_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +### List Consumers + +##### List All Consumers + +
/consumers
+ + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.consumer_data }} + "next": "http://localhost:8001/consumers?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Consumer + +##### Retrieve Consumer + +
/consumers/{consumer username or id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to retrieve. + + +##### Retrieve Consumer Associated to a Specific Plugin + +
/plugins/{plugin id}/consumer
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Consumer to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +### Update Consumer + +##### Update Consumer + +
/consumers/{consumer username or id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to update. + + +##### Update Consumer Associated to a Specific Plugin + +
/plugins/{plugin id}/consumer
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Consumer to be updated. + + +#### Request Body + +{{ page.consumer_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +### Update Or Create Consumer + +##### Create Or Update Consumer + +
/consumers/{consumer username or id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to create or update. + + +##### Create Or Update Consumer Associated to a Specific Plugin + +
/plugins/{plugin id}/consumer
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Consumer to be created or updated. + + +#### Request Body + +{{ page.consumer_body }} + + +Inserts (or replaces) the Consumer under the requested resource with the +definition specified in the body. The Consumer will be identified via the `username +or id` attribute. + +When the `username or id` attribute has the structure of a UUID, the Consumer being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `username`. + +When creating a new Consumer without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `username` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Consumer + +##### Delete Consumer + +
/consumers/{consumer username or id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Plugin Object + +A Plugin entity represents a plugin configuration that will be executed during +the HTTP request/response lifecycle. It is how you can add functionalities +to Services that run behind Kong, like Authentication or Rate Limiting for +example. You can find more information about how to install and what values +each plugin takes by visiting the [Kong Hub](https://docs.konghq.com/hub/). + +When adding a Plugin Configuration to a Service, every request made by a client to +that Service will run said Plugin. If a Plugin needs to be tuned to different +values for some specific Consumers, you can do so by creating a separate +plugin instance that specifies both the Service and the Consumer, through the +`service` and `consumer` fields. + +Plugins can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.plugin_json }} +``` + +See the [Precedence](#precedence) section below for more details. + +#### Precedence + +A plugin will always be run once and only once per request. But the +configuration with which it will run depends on the entities it has been +configured for. + +Plugins can be configured for various entities, combination of entities, or +even globally. This is useful, for example, when you wish to configure a plugin +a certain way for most requests, but make _authenticated requests_ behave +slightly differently. + +Therefore, there exists an order of precedence for running a plugin when it has +been applied to different entities with different configurations. The rule of +thumb is: the more specific a plugin is with regards to how many entities it +has been configured on, the higher its priority. + +The complete order of precedence when a plugin has been configured multiple +times is: + +1. Plugins configured on a combination of: a Route, a Service, and a Consumer. + (Consumer means the request must be authenticated). +2. Plugins configured on a combination of a Route and a Consumer. + (Consumer means the request must be authenticated). +3. Plugins configured on a combination of a Service and a Consumer. + (Consumer means the request must be authenticated). +4. Plugins configured on a combination of a Route and a Service. +5. Plugins configured on a Consumer. + (Consumer means the request must be authenticated). +6. Plugins configured on a Route. +7. Plugins configured on a Service. +8. Plugins configured to run globally. + +**Example**: if the `rate-limiting` plugin is applied twice (with different +configurations): for a Service (Plugin config A), and for a Consumer (Plugin +config B), then requests authenticating this Consumer will run Plugin config B +and ignore A. However, requests that do not authenticate this Consumer will +fallback to running Plugin config A. Note that if config B is disabled +(its `enabled` flag is set to `false`), config A will apply to requests that +would have otherwise matched config B. + + +### Add Plugin + +##### Create Plugin + +
/plugins
+ + +##### Create Plugin Associated to a Specific Route + +
/routes/{route name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier or the `name` attribute of the Route that should be associated to the newly-created Plugin. + + +##### Create Plugin Associated to a Specific Service + +
/services/{service name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier or the `name` attribute of the Service that should be associated to the newly-created Plugin. + + +##### Create Plugin Associated to a Specific Consumer + +
/consumers/{consumer name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`consumer name or id`
**required** | The unique identifier or the `name` attribute of the Consumer that should be associated to the newly-created Plugin. + + +#### Request Body + +{{ page.plugin_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### List Plugins + +##### List All Plugins + +
/plugins
+ + +##### List Plugins Associated to a Specific Route + +
/routes/{route name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier or the `name` attribute of the Route whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Route will be listed. + + +##### List Plugins Associated to a Specific Service + +
/services/{service name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier or the `name` attribute of the Service whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Service will be listed. + + +##### List Plugins Associated to a Specific Consumer + +
/consumers/{consumer name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`consumer name or id`
**required** | The unique identifier or the `name` attribute of the Consumer whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Consumer will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.plugin_data }} + "next": "http://localhost:8001/plugins?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Plugin + +##### Retrieve Plugin + +
/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Route + +
/routes/{route name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to retrieve. +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Service + +
/services/{service name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Consumer + +
/consumers/{consumer username or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to retrieve. +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### Update Plugin + +##### Update Plugin + +
/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin to update. + + +##### Update Plugin Associated to a Specific Route + +
/routes/{route name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to update. +`plugin id`
**required** | The unique identifier of the Plugin to update. + + +##### Update Plugin Associated to a Specific Service + +
/services/{service name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to update. +`plugin id`
**required** | The unique identifier of the Plugin to update. + + +##### Update Plugin Associated to a Specific Consumer + +
/consumers/{consumer username or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to update. +`plugin id`
**required** | The unique identifier of the Plugin to update. + + +#### Request Body + +{{ page.plugin_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### Update Or Create Plugin + +##### Create Or Update Plugin + +
/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin to create or update. + + +##### Create Or Update Plugin Associated to a Specific Route + +
/routes/{route name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to create or update. +`plugin id`
**required** | The unique identifier of the Plugin to create or update. + + +##### Create Or Update Plugin Associated to a Specific Service + +
/services/{service name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to create or update. +`plugin id`
**required** | The unique identifier of the Plugin to create or update. + + +##### Create Or Update Plugin Associated to a Specific Consumer + +
/consumers/{consumer username or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to create or update. +`plugin id`
**required** | The unique identifier of the Plugin to create or update. + + +#### Request Body + +{{ page.plugin_body }} + + +Inserts (or replaces) the Plugin under the requested resource with the +definition specified in the body. The Plugin will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Plugin being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Plugin without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Plugin + +##### Delete Plugin + +
/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin to delete. + + +##### Delete Plugin Associated to a Specific Route + +
/routes/{route name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to delete. +`plugin id`
**required** | The unique identifier of the Plugin to delete. + + +##### Delete Plugin Associated to a Specific Service + +
/services/{service name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to delete. +`plugin id`
**required** | The unique identifier of the Plugin to delete. + + +##### Delete Plugin Associated to a Specific Consumer + +
/consumers/{consumer username or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to delete. +`plugin id`
**required** | The unique identifier of the Plugin to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Retrieve Enabled Plugins + +Retrieve a list of all installed plugins on the Kong node. + +
/plugins/enabled
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "enabled_plugins": [ + "jwt", + "acl", + "cors", + "oauth2", + "tcp-log", + "udp-log", + "file-log", + "http-log", + "key-auth", + "hmac-auth", + "basic-auth", + "ip-restriction", + "request-transformer", + "response-transformer", + "request-size-limiting", + "rate-limiting", + "response-ratelimiting", + "aws-lambda", + "bot-detection", + "correlation-id", + "datadog", + "galileo", + "ldap-auth", + "loggly", + "statsd", + "syslog" + ] +} +``` + + +--- + +## Certificate Object + +A certificate object represents a public certificate, and can be optionally paired with the +corresponding private key. These objects are used by Kong to handle SSL/TLS termination for +encrypted requests, or for use as a trusted CA store when validating peer certificate of +client/service. Certificates are optionally associated with SNI objects to +tie a cert/key pair to one or more hostnames. + +If intermediate certificates are required in addition to the main +certificate, they should be concatenated together into one string according to +the following order: main certificate on the top, followed by any intermediates. + +Certificates can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.certificate_json }} +``` + +### Add Certificate + +##### Create Certificate + +
/certificates
+ + +#### Request Body + +{{ page.certificate_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +### List Certificates + +##### List All Certificates + +
/certificates
+ + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.certificate_data }} + "next": "http://localhost:8001/certificates?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Certificate + +##### Retrieve Certificate + +
/certificates/{certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. + + +##### Retrieve Certificate Associated to a Specific Upstream + +
/upstreams/{upstream name or id}/client_certificate
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +### Update Certificate + +##### Update Certificate + +
/certificates/{certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to update. + + +##### Update Certificate Associated to a Specific Upstream + +
/upstreams/{upstream name or id}/client_certificate
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be updated. + + +#### Request Body + +{{ page.certificate_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +### Update Or Create Certificate + +##### Create Or Update Certificate + +
/certificates/{certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to create or update. + + +##### Create Or Update Certificate Associated to a Specific Upstream + +
/upstreams/{upstream name or id}/client_certificate
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be created or updated. + + +#### Request Body + +{{ page.certificate_body }} + + +Inserts (or replaces) the Certificate under the requested resource with the +definition specified in the body. The Certificate will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Certificate being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Certificate without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Certificate + +##### Delete Certificate + +
/certificates/{certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to delete. + + +##### Delete Certificate Associated to a Specific Upstream + +
/upstreams/{upstream name or id}/client_certificate
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be deleted. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## CA Certificate Object + +A CA certificate object represents a trusted CA. These objects are used by Kong to +verify the validity of a client or server certificate. + +CA Certificates can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.ca_certificate_json }} +``` + +### Add CA Certificate + +##### Create CA Certificate + +
/ca_certificates
+ + +#### Request Body + +{{ page.ca_certificate_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +### List CA Certificates + +##### List All CA Certificates + +
/ca_certificates
+ + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.ca_certificate_data }} + "next": "http://localhost:8001/ca_certificates?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve CA Certificate + +##### Retrieve CA Certificate + +
/ca_certificates/{ca_certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
**required** | The unique identifier of the CA Certificate to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +### Update CA Certificate + +##### Update CA Certificate + +
/ca_certificates/{ca_certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
**required** | The unique identifier of the CA Certificate to update. + + +#### Request Body + +{{ page.ca_certificate_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +### Update Or Create CA Certificate + +##### Create Or Update CA Certificate + +
/ca_certificates/{ca_certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
**required** | The unique identifier of the CA Certificate to create or update. + + +#### Request Body + +{{ page.ca_certificate_body }} + + +Inserts (or replaces) the CA Certificate under the requested resource with the +definition specified in the body. The CA Certificate will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the CA Certificate being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new CA Certificate without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete CA Certificate + +##### Delete CA Certificate + +
/ca_certificates/{ca_certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
**required** | The unique identifier of the CA Certificate to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## SNI Object + +An SNI object represents a many-to-one mapping of hostnames to a certificate. +That is, a certificate object can have many hostnames associated with it; when +Kong receives an SSL request, it uses the SNI field in the Client Hello to +lookup the certificate object based on the SNI associated with the certificate. + +SNIs can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.sni_json }} +``` + +### Add SNI + +##### Create SNI + +
/snis
+ + +##### Create SNI Associated to a Specific Certificate + +
/certificates/{certificate name or id}/snis
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate that should be associated to the newly-created SNI. + + +#### Request Body + +{{ page.sni_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.sni_json }} +``` + + +--- + +### List SNIs + +##### List All SNIs + +
/snis
+ + +##### List SNIs Associated to a Specific Certificate + +
/certificates/{certificate name or id}/snis
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate whose SNIs are to be retrieved. When using this endpoint, only SNIs associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.sni_data }} + "next": "http://localhost:8001/snis?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve SNI + +##### Retrieve SNI + +
/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to retrieve. + + +##### Retrieve SNI Associated to a Specific Certificate + +
/certificates/{certificate id}/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.sni_json }} +``` + + +--- + +### Update SNI + +##### Update SNI + +
/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to update. + + +##### Update SNI Associated to a Specific Certificate + +
/certificates/{certificate id}/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to update. +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to update. + + +#### Request Body + +{{ page.sni_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.sni_json }} +``` + + +--- + +### Update Or Create SNI + +##### Create Or Update SNI + +
/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to create or update. + + +##### Create Or Update SNI Associated to a Specific Certificate + +
/certificates/{certificate id}/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to create or update. +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to create or update. + + +#### Request Body + +{{ page.sni_body }} + + +Inserts (or replaces) the SNI under the requested resource with the +definition specified in the body. The SNI will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the SNI being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new SNI without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete SNI + +##### Delete SNI + +
/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to delete. + + +##### Delete SNI Associated to a Specific Certificate + +
/certificates/{certificate id}/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to delete. +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to delete. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +## Upstream Object + +The upstream object represents a virtual hostname and can be used to loadbalance +incoming requests over multiple services (targets). So for example an upstream +named `service.v1.xyz` for a Service object whose `host` is `service.v1.xyz`. +Requests for this Service would be proxied to the targets defined within the upstream. + +An upstream also includes a [health checker][healthchecks], which is able to +enable and disable targets based on their ability or inability to serve +requests. The configuration for the health checker is stored in the upstream +object, and applies to all of its targets. + +Upstreams can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.upstream_json }} +``` + +### Add Upstream + +##### Create Upstream + +
/upstreams
+ + +##### Create Upstream Associated to a Specific Certificate + +
/certificates/{certificate name or id}/upstreams
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate that should be associated to the newly-created Upstream. + + +#### Request Body + +{{ page.upstream_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### List Upstreams + +##### List All Upstreams + +
/upstreams
+ + +##### List Upstreams Associated to a Specific Certificate + +
/certificates/{certificate name or id}/upstreams
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate whose Upstreams are to be retrieved. When using this endpoint, only Upstreams associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.upstream_data }} + "next": "http://localhost:8001/upstreams?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Upstream + +##### Retrieve Upstream + +
/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to retrieve. + + +##### Retrieve Upstream Associated to a Specific Certificate + +
/certificates/{certificate id}/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to retrieve. + + +##### Retrieve Upstream Associated to a Specific Target + +
/targets/{target host:port or id}/upstream
+ +{:.indent} +Attributes | Description +---:| --- +`target host:port or id`
**required** | The unique identifier **or** the host:port of the Target associated to the Upstream to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### Update Upstream + +##### Update Upstream + +
/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to update. + + +##### Update Upstream Associated to a Specific Certificate + +
/certificates/{certificate id}/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to update. +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to update. + + +##### Update Upstream Associated to a Specific Target + +
/targets/{target host:port or id}/upstream
+ +{:.indent} +Attributes | Description +---:| --- +`target host:port or id`
**required** | The unique identifier **or** the host:port of the Target associated to the Upstream to be updated. + + +#### Request Body + +{{ page.upstream_body }} + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### Update Or Create Upstream + +##### Create Or Update Upstream + +
/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to create or update. + + +##### Create Or Update Upstream Associated to a Specific Certificate + +
/certificates/{certificate id}/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to create or update. +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to create or update. + + +##### Create Or Update Upstream Associated to a Specific Target + +
/targets/{target host:port or id}/upstream
+ +{:.indent} +Attributes | Description +---:| --- +`target host:port or id`
**required** | The unique identifier **or** the host:port of the Target associated to the Upstream to be created or updated. + + +#### Request Body + +{{ page.upstream_body }} + + +Inserts (or replaces) the Upstream under the requested resource with the +definition specified in the body. The Upstream will be identified via the `name +or id` attribute. + +When the `name or id` attribute has the structure of a UUID, the Upstream being +inserted/replaced will be identified by its `id`. Otherwise it will be +identified by its `name`. + +When creating a new Upstream without specifying `id` (neither in the URL nor in +the body), then it will be auto-generated. + +Notice that specifying a `name` in the URL and a different one in the request +body is not allowed. + + +#### Response + +``` +HTTP 201 Created or HTTP 200 OK +``` + +See POST and PATCH responses. + + +--- + +### Delete Upstream + +##### Delete Upstream + +
/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to delete. + + +##### Delete Upstream Associated to a Specific Certificate + +
/certificates/{certificate id}/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to delete. +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to delete. + + +##### Delete Upstream Associated to a Specific Target + +
/targets/{target host:port or id}/upstream
+ +{:.indent} +Attributes | Description +---:| --- +`target host:port or id`
**required** | The unique identifier **or** the host:port of the Target associated to the Upstream to be deleted. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Show Upstream Health for Node + +Displays the health status for all Targets of a given Upstream, or for +the whole Upstream, according to the perspective of a specific Kong node. +Note that, being node-specific information, making this same request +to different nodes of the Kong cluster may produce different results. +For example, one specific node of the Kong cluster may be experiencing +network issues, causing it to fail to connect to some Targets: these +Targets will be marked as unhealthy by that node (directing traffic from +this node to other Targets that it can successfully reach), but healthy +to all others Kong nodes (which have no problems using that Target). + +The `data` field of the response contains an array of Target objects. +The health for each Target is returned in its `health` field: + +* If a Target fails to be activated in the balancer due to DNS issues, + its status displays as `DNS_ERROR`. +* When [health checks][healthchecks] are not enabled in the Upstream + configuration, the health status for active Targets is displayed as + `HEALTHCHECKS_OFF`. +* When health checks are enabled and the Target is determined to be healthy, + either automatically or [manually](#set-target-as-healthy), + its status is displayed as `HEALTHY`. This means that this Target is + currently included in this Upstream's load balancer execution. +* When a Target has been disabled by either active or passive health checks + (circuit breakers) or [manually](#set-target-as-unhealthy), + its status is displayed as `UNHEALTHY`. The load balancer is not directing + any traffic to this Target via this Upstream. + +When the request query parameter `balancer_health` is set to `1`, the +`data` field of the response refers to the Upstream itself, and its `health` +attribute is defined by the state of all of Upstream's Targets, according +to the field `healthchecks.threshold`. + + +
/upstreams/{name or id}/health/
+ +{:.indent} +Attributes | Description +---:| --- +`name or id`
**required** | The unique identifier **or** the name of the Upstream for which to display Target health. + + +#### Request Querystring Parameters + +Attributes | Description +---:| --- +`balancer_health`
*optional* | If set to 1, Kong will return the health status of the Upstream itself. See the `healthchecks.threshold` property. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "total": 2, + "node_id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9", + "data": [ + { + "created_at": 1485524883980, + "id": "18c0ad90-f942-4098-88db-bbee3e43b27f", + "health": "HEALTHY", + "target": "127.0.0.1:20000", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 100 + }, + { + "created_at": 1485524914883, + "id": "6c6f34eb-e6c3-4c1f-ac58-4060e5bca890", + "health": "UNHEALTHY", + "target": "127.0.0.1:20002", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 200 + } + ] +} +``` + +If `balancer_health=1`: +``` +HTTP 200 OK +``` + +```json +{ + "data": { + "health": "HEALTHY", + "id": "07131005-ba30-4204-a29f-0927d53257b4" + }, + "next": null, + "node_id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9" +} +``` + + +--- + +## Target Object + +A target is an ip address/hostname with a port that identifies an instance of a backend +service. Every upstream can have many targets, and the targets can be +dynamically added. Changes are effectuated on the fly. + +Because the upstream maintains a history of target changes, the targets cannot +be deleted or modified. To disable a target, post a new one with `weight=0`; +alternatively, use the `DELETE` convenience method to accomplish the same. + +The current target object definition is the one with the latest `created_at`. + +Targets can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.target_json }} +``` + +### Add Target + +##### Create Target Associated to a Specific Upstream + +
/upstreams/{upstream host:port or id}/targets
+ +{:.indent} +Attributes | Description +---:| --- +`upstream host:port or id`
**required** | The unique identifier or the `host:port` attribute of the Upstream that should be associated to the newly-created Target. + + +#### Request Body + +{{ page.target_body }} + + +#### Response + +``` +HTTP 201 Created +``` + +```json +{{ page.target_json }} +``` + + +--- + +### List Targets + +##### List Targets Associated to a Specific Upstream + +
/upstreams/{upstream host:port or id}/targets
+ +{:.indent} +Attributes | Description +---:| --- +`upstream host:port or id`
**required** | The unique identifier or the `host:port` attribute of the Upstream whose Targets are to be retrieved. When using this endpoint, only Targets associated to the specified Upstream will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.target_data }} + "next": "http://localhost:8001/targets?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Delete Target + +Disable a target in the load balancer. Under the hood, this method creates +a new entry for the given target definition with a `weight` of 0. + + +
/upstreams/{upstream name or id}/targets/{host:port or id}
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream for which to delete the target. +`host:port or id`
**required** | The host:port combination element of the target to remove, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target Address As Healthy + +Set the current health status of an individual address resolved by a target +in the load balancer to "healthy" in the entire Kong cluster. + +This endpoint can be used to manually re-enable an address resolved by a +target that was previously disabled by the upstream's [health checker][healthchecks]. +Upstreams only forward requests to healthy nodes, so this call tells Kong +to start using this address again. + +This resets the health counters of the health checkers running in all workers +of the Kong node, and broadcasts a cluster-wide message so that the "healthy" +status is propagated to the whole Kong cluster. + + +
/upstreams/{upstream name or id}/targets/{target or id}/{address}/healthy
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream. +`target or id`
**required** | The host/port combination element of the target to set as healthy, or the `id` of an existing target entry. +`address`
**required** | The host/port combination element of the address to set as healthy. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target Address As Unhealthy + +Set the current health status of an individual address resolved by a target +in the load balancer to "unhealthy" in the entire Kong cluster. + +This endpoint can be used to manually disable an address and have it stop +responding to requests. Upstreams only forward requests to healthy nodes, so +this call tells Kong to start skipping this address. + +This call resets the health counters of the health checkers running in all +workers of the Kong node, and broadcasts a cluster-wide message so that the +"unhealthy" status is propagated to the whole Kong cluster. + +[Active health checks][active] continue to execute for unhealthy +addresses. Note that if active health checks are enabled and the probe detects +that the address is actually healthy, it will automatically re-enable it again. +To permanently remove a target from the balancer, you should [delete a +target](#delete-target) instead. + + +
/upstreams/{upstream name or id}/targets/{target or id}/unhealthy
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream. +`target or id`
**required** | The host/port combination element of the target to set as unhealthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target As Healthy + +Set the current health status of a target in the load balancer to "healthy" +in the entire Kong cluster. This sets the "healthy" status to all addresses +resolved by this target. + +This endpoint can be used to manually re-enable a target that was previously +disabled by the upstream's [health checker][healthchecks]. Upstreams only +forward requests to healthy nodes, so this call tells Kong to start using this +target again. + +This resets the health counters of the health checkers running in all workers +of the Kong node, and broadcasts a cluster-wide message so that the "healthy" +status is propagated to the whole Kong cluster. + + +
/upstreams/{upstream name or id}/targets/{target or id}/healthy
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream. +`target or id`
**required** | The host/port combination element of the target to set as healthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target As Unhealthy + +Set the current health status of a target in the load balancer to "unhealthy" +in the entire Kong cluster. This sets the "unhealthy" status to all addresses +resolved by this target. + +This endpoint can be used to manually disable a target and have it stop +responding to requests. Upstreams only forward requests to healthy nodes, so +this call tells Kong to start skipping this target. + +This call resets the health counters of the health checkers running in all +workers of the Kong node, and broadcasts a cluster-wide message so that the +"unhealthy" status is propagated to the whole Kong cluster. + +[Active health checks][active] continue to execute for unhealthy +targets. Note that if active health checks are enabled and the probe detects +that the target is actually healthy, it will automatically re-enable it again. +To permanently remove a target from the balancer, you should [delete a +target](#delete-target) instead. + + +
/upstreams/{upstream name or id}/targets/{target or id}/unhealthy
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream. +`target or id`
**required** | The host/port combination element of the target to set as unhealthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### List All Targets + +Lists all targets of the upstream. Multiple target objects for the same +target may be returned, showing the history of changes for a specific target. +The target object with the latest `created_at` is the current definition. + + +
/upstreams/{name or id}/targets/all/
+ +{:.indent} +Attributes | Description +---:| --- +`name or id`
**required** | The unique identifier **or** the name of the upstream for which to list the targets. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "total": 2, + "data": [ + { + "created_at": 1485524883980, + "id": "18c0ad90-f942-4098-88db-bbee3e43b27f", + "target": "127.0.0.1:20000", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 100 + }, + { + "created_at": 1485524914883, + "id": "6c6f34eb-e6c3-4c1f-ac58-4060e5bca890", + "target": "127.0.0.1:20002", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 200 + } + ] +} +``` + + +--- + +[clustering]: /{{page.kong_version}}/clustering +[cli]: /{{page.kong_version}}/cli +[active]: /{{page.kong_version}}/health-checks-circuit-breakers/#active-health-checks +[healthchecks]: /{{page.kong_version}}/health-checks-circuit-breakers +[secure-admin-api]: /{{page.kong_version}}/secure-admin-api +[proxy-reference]: /{{page.kong_version}}/proxy +[db-less-admin-api]: /{{page.kong_version}}/db-less-admin-api diff --git a/app/2.2.x/auth.md b/app/2.2.x/auth.md new file mode 100644 index 000000000000..c9ce4550b49b --- /dev/null +++ b/app/2.2.x/auth.md @@ -0,0 +1,216 @@ +--- +title: Authentication Reference +skip_read_time: true +--- + +## Introduction + +Traffic to your Upstream services (APIs or microservices) is typically controlled by the application and +configuration of various Kong [authentication plugins][plugins]. Because Kong's Service entity represents +a 1-to-1 mapping of your own upstream services, the simplest scenario is to configure authentication +plugins on the Services of your choosing. + +## Generic authentication + +The most common scenario is to require authentication and to not allow access for any unauthenticated request. +To achieve this, any of the authentication plugins can be used. The generic scheme/flow of those plugins +works as follows: + +1. Apply an auth plugin to a Service, or globally (you cannot apply one on consumers) +2. Create a `consumer` entity +3. Provide the consumer with authentication credentials for the specific authentication method +4. Now whenever a request comes in, Kong will check the provided credentials (depends on the auth type) and +it will either block the request if it cannot validate, or add consumer and credential details +in the headers and forward the request. + +The generic flow above does not always apply, for example when using external authentication like LDAP, +then there is no consumer to be identified, and only the credentials will be added in the forwarded headers. + +The authentication method specific elements and examples can be found in each [plugin's documentation][plugins]. + +## Consumers + +The easiest way to think about consumers is to map them one-on-one to users. Yet, to Kong this does not matter. +The core principle for consumers is that you can attach plugins to them, and hence customize request behaviour. +So you might have mobile apps, and define one consumer for each app, or version of it. Or have a consumer per +platform, e.g. an android consumer, an iOS consumer, etc. + +It is an opaque concept to Kong and hence they are called "consumers" and not "users". + +## Anonymous Access + +Kong has the ability to configure a given Service to allow **both** authenticated **and** anonymous access. +You might use this configuration to grant access to anonymous users with a low rate limit, and grant access +to authenticated users with a higher rate limit. + +To configure a Service like this, you first apply your selected authentication plugin, then create a new +consumer to represent anonymous users, then configure your authentication plugin to allow anonymous +access. Here is an example, which assumes you have already configured a Service named `example-service` and +the corresponding Route: + +1. ### Create an example Service and a Route + + Issue the following cURL request to create `example-service` pointing to `mockbin.org`, which will echo + the request: + + ```bash + $ curl -i -X POST \ + --url http://localhost:8001/services/ \ + --data 'name=example-service' \ + --data 'url=http://mockbin.org/request' + ``` + + Add a Route to the Service: + + ```bash + $ curl -i -X POST \ + --url http://localhost:8001/services/example-service/routes \ + --data 'paths[]=/auth-sample' + ``` + + The url `http://localhost:8000/auth-sample` will now echo whatever is being requested. + +2. ### Configure the key-auth Plugin for your Service + + Issue the following cURL request to add a plugin to a Service: + + ```bash + $ curl -i -X POST \ + --url http://localhost:8001/services/example-service/plugins/ \ + --data 'name=key-auth' + ``` + + Be sure to note the created Plugin `id` - you'll need it in step 5. + +3. ### Verify that the key-auth plugin is properly configured + + Issue the following cURL request to verify that the [key-auth][key-auth] + plugin was properly configured on the Service: + + ```bash + $ curl -i -X GET \ + --url http://localhost:8000/auth-sample + ``` + + Since you did not specify the required `apikey` header or parameter, and you have not yet + enabled anonymous access, the response should be `403 Forbidden`: + + ```http + HTTP/1.1 403 Forbidden + ... + + { + "message": "No API key found in headers or querystring" + } + ``` + +4. ### Create an anonymous Consumer + + Every request proxied by Kong must be associated with a Consumer. You'll now create a Consumer + named `anonymous_users` (that Kong will utilize when proxying anonymous access) by issuing the + following request: + + ```bash + $ curl -i -X POST \ + --url http://localhost:8001/consumers/ \ + --data "username=anonymous_users" + ``` + + You should see a response similar to the one below: + + ```http + HTTP/1.1 201 Created + Content-Type: application/json + Connection: keep-alive + + { + "username": "anonymous_users", + "created_at": 1428555626000, + "id": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9" + } + ``` + + Be sure to note the Consumer `id` - you'll need it in the next step. + +5. ### Enable anonymous access + + You'll now re-configure the key-auth plugin to permit anonymous access by issuing the following + request (**replace the sample uuids below by the `id` values from step 2 and 4**): + + ```bash + $ curl -i -X PATCH \ + --url http://localhost:8001/plugins/ \ + --data "config.anonymous=" + ``` + + The `config.anonymous=` parameter instructs the key-auth plugin on this Service to permit + anonymous access, and to associate such access with the Consumer `id` we received in the previous step. It is + required that you provide a valid and pre-existing Consumer `id` in this step - validity of the Consumer `id` + is not currently checked when configuring anonymous access, and provisioning of a Consumer `id` that doesn't already + exist will result in an incorrect configuration. + +6. ### Check anonymous access + + Confirm that your Service now permits anonymous access by issuing the following request: + + ```bash + $ curl -i -X GET \ + --url http://localhost:8000/auth-sample + ``` + + This is the same request you made in step #3; however, this time the request should succeed because you + enabled anonymous access in step #5. + + The response (which is the request as Mockbin received it) should have these elements: + + ```json + { + ... + "headers": { + ... + "x-consumer-id": "713c592c-38b8-4f5b-976f-1bd2b8069494", + "x-consumer-username": "anonymous_users", + "x-anonymous-consumer": "true", + ... + }, + ... + } + ``` + + It shows the request was successful, but anonymous. + +## Multiple Authentication + +Kong supports multiple authentication plugins for a given Service, allowing +different clients to utilize different authentication methods to access a given Service or Route. + +The behaviour of the auth plugins can be set to do either a logical `AND`, or a logical `OR` when evaluating +multiple authentication credentials. The key to the behaviour is the `config.anonymous` property. + +- `config.anonymous` not set
+ If this property is not set (empty), then the auth plugins will always perform authentication and return + a `40x` response if not validated. This results in a logical `AND` when multiple auth plugins are being + invoked. +- `config.anonymous` set to a valid consumer id
+ In this case, the auth plugin will only perform authentication if it was not already authenticated. When + authentication fails, it will not return a `40x` response, but set the anonymous consumer as the consumer. This + results in a logical `OR` + 'anonymous access' when multiple auth plugins are being invoked. + +**NOTE 1**: Either all or none of the auth plugins must be configured for anonymous access. The behaviour is +undefined if they are mixed. + +**NOTE 2**: When using the `AND` method, the last plugin executed will be the one setting the credentials +passed to the upstream service. With the `OR` method, it will be the first plugin that successfully authenticates +the consumer, or the last plugin that will set its configured anonymous consumer. + +**NOTE 3**: When using the OAuth2 plugin in an `AND` fashion, then also the OAuth2 endpoints for requesting +tokens and so forth will require authentication by the other configured auth plugins. + +
+ When multiple authentication plugins are enabled in an OR fashion on a given Service, and it is desired that + anonymous access be forbidden, then the request-termination plugin should be + configured on the anonymous consumer. Failure to do so will allow unauthorized requests. +
+ +[plugins]: https://konghq.com/plugins/ +[key-auth]: /plugins/key-authentication diff --git a/app/2.2.x/cli.md b/app/2.2.x/cli.md new file mode 100644 index 000000000000..64f0a651e78d --- /dev/null +++ b/app/2.2.x/cli.md @@ -0,0 +1,346 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# the files in https://github.com/Kong/kong/tree/master/autodoc/cli +# +title: CLI Reference +skip_read_time: true +--- + +## Introduction + +The provided CLI (*Command Line Interface*) allows you to start, stop, and +manage your Kong instances. The CLI manages your local node (as in, on the +current machine). + +If you haven't yet, we recommend you read the [configuration reference][configuration-reference]. + +## Global flags + +All commands take a set of special, optional flags as arguments: + +* `--help`: print the command's help message +* `--v`: enable verbose mode +* `--vv`: enable debug mode (noisy) + +[Back to top](#introduction) + +## Available commands + + +### kong check + +``` +Usage: kong check + +Check the validity of a given Kong configuration file. + + (default /etc/kong/kong.conf) configuration file + +``` + +[Back to top](#introduction) + +--- + + +### kong config + +``` +Usage: kong config COMMAND [OPTIONS] + +Use declarative configuration files with Kong. + +The available commands are: + init [] Generate an example config file to + get you started. If a filename + is not given, ./kong.yml is used + by default. + + db_import Import a declarative config file into + the Kong database. + + db_export [] Export the Kong database into a + declarative config file. If a filename + is not given, ./kong.yml is used + by default. + + parse Parse a declarative config file (check + its syntax) but do not load it into Kong. + +Options: + -c,--conf (optional string) Configuration file. + -p,--prefix (optional string) Override prefix directory. + +``` + +[Back to top](#introduction) + +--- + + +### kong health + +``` +Usage: kong health [OPTIONS] + +Check if the necessary services are running for this node. + +Options: + -p,--prefix (optional string) prefix at which Kong should be running + +``` + +[Back to top](#introduction) + +--- + + +### kong hybrid + +``` +Usage: kong hybrid COMMAND [OPTIONS] + +Hybrid mode utilities for Kong. + +The available commands are: + gen_cert [ ] Generate a certificate/key pair that is suitable + for use in hybrid mode deployment. + Cert and key will be written to + './cluster.crt' and './cluster.key' inside + the current directory unless filenames are given. + +Options: + -d,--days (optional number) Override certificate validity duration. + Default: 1095 days (3 years) + +``` + +[Back to top](#introduction) + +--- + + +### kong migrations + +``` +Usage: kong migrations COMMAND [OPTIONS] + +Manage database schema migrations. + +The available commands are: + bootstrap Bootstrap the database and run all + migrations. + + up Run any new migrations. + + finish Finish running any pending migrations after + 'up'. + + list List executed migrations. + + reset Reset the database. + +Options: + -y,--yes Assume "yes" to prompts and run + non-interactively. + + -q,--quiet Suppress all output. + + -f,--force Run migrations even if database reports + as already executed. + + --db-timeout (default 60) Timeout, in seconds, for all database + operations (including schema consensus for + Cassandra). + + --lock-timeout (default 60) Timeout, in seconds, for nodes waiting on + the leader node to finish running + migrations. + + -c,--conf (optional string) Configuration file. + + +``` + +[Back to top](#introduction) + +--- + + +### kong prepare + +This command prepares the Kong prefix folder, with its sub-folders and files. + +``` +Usage: kong prepare [OPTIONS] + +Prepare the Kong prefix in the configured prefix directory. This command can +be used to start Kong from the nginx binary without using the 'kong start' +command. + +Example usage: + kong migrations up + kong prepare -p /usr/local/kong -c kong.conf + nginx -p /usr/local/kong -c /usr/local/kong/nginx.conf + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) override prefix directory + --nginx-conf (optional string) custom Nginx configuration template + +``` + +[Back to top](#introduction) + +--- + + +### kong quit + +``` +Usage: kong quit [OPTIONS] + +Gracefully quit a running Kong node (Nginx and other +configured services) in given prefix directory. + +This command sends a SIGQUIT signal to Nginx, meaning all +requests will finish processing before shutting down. +If the timeout delay is reached, the node will be forcefully +stopped (SIGTERM). + +Options: + -p,--prefix (optional string) prefix Kong is running at + -t,--timeout (default 10) timeout before forced shutdown + -w,--wait (default 0) wait time before initiating the shutdown + +``` + +[Back to top](#introduction) + +--- + + +### kong reload + +``` +Usage: kong reload [OPTIONS] + +Reload a Kong node (and start other configured services +if necessary) in given prefix directory. + +This command sends a HUP signal to Nginx, which will spawn +new workers (taking configuration changes into account), +and stop the old ones when they have finished processing +current requests. + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) prefix Kong is running at + --nginx-conf (optional string) custom Nginx configuration template + +``` + +[Back to top](#introduction) + +--- + + +### kong restart + +``` +Usage: kong restart [OPTIONS] + +Restart a Kong node (and other configured services like Serf) +in the given prefix directory. + +This command is equivalent to doing both 'kong stop' and +'kong start'. + +Options: + -c,--conf (optional string) configuration file + -p,--prefix (optional string) prefix at which Kong should be running + --nginx-conf (optional string) custom Nginx configuration template + --run-migrations (optional boolean) optionally run migrations on the DB + --db-timeout (default 60) + --lock-timeout (default 60) + +``` + +[Back to top](#introduction) + +--- + + +### kong start + +``` +Usage: kong start [OPTIONS] + +Start Kong (Nginx and other configured services) in the configured +prefix directory. + +Options: + -c,--conf (optional string) Configuration file. + + -p,--prefix (optional string) Override prefix directory. + + --nginx-conf (optional string) Custom Nginx configuration template. + + --run-migrations (optional boolean) Run migrations before starting. + + --db-timeout (default 60) Timeout, in seconds, for all database + operations (including schema consensus for + Cassandra). + + --lock-timeout (default 60) When --run-migrations is enabled, timeout, + in seconds, for nodes waiting on the + leader node to finish running migrations. + +``` + +[Back to top](#introduction) + +--- + + +### kong stop + +``` +Usage: kong stop [OPTIONS] + +Stop a running Kong node (Nginx and other configured services) in given +prefix directory. + +This command sends a SIGTERM signal to Nginx. + +Options: + -p,--prefix (optional string) prefix Kong is running at + +``` + +[Back to top](#introduction) + +--- + + +### kong version + +``` +Usage: kong version [OPTIONS] + +Print Kong's version. With the -a option, will print +the version of all underlying dependencies. + +Options: + -a,--all get version of all dependencies + +``` + +[Back to top](#introduction) + +--- + + +[configuration-reference]: /{{page.kong_version}}/configuration diff --git a/app/2.2.x/clustering.md b/app/2.2.x/clustering.md new file mode 100644 index 000000000000..47f40ecbad33 --- /dev/null +++ b/app/2.2.x/clustering.md @@ -0,0 +1,301 @@ +--- +title: Clustering Reference +skip_read_time: true +--- + +## Introduction + +A Kong cluster allows you to scale the system horizontally by adding more +machines to handle more incoming requests. They will all share the same +configuration since they point to the same database. Kong nodes pointing to the +**same datastore** will be part of the same Kong cluster. + +You need a load-balancer in front of your Kong cluster to distribute traffic +across your available nodes. + +## What a Kong cluster does and doesn't do + +**Having a Kong cluster does not mean that your clients traffic will be +load-balanced across your Kong nodes out of the box.** You still need a +load-balancer in front of your Kong nodes to distribute your traffic. Instead, +a Kong cluster means that those nodes will share the same configuration. + +For performance reasons, Kong avoids database connections when proxying +requests, and caches the contents of your database in memory. The cached +entities include Services, Routes, Consumers, Plugins, Credentials, and so forth. Since those +values are in memory, any change made via the Admin API of one of the nodes +needs to be propagated to the other nodes. + +This document describes how those cached entities are being invalidated and how +to configure your Kong nodes for your use case, which lies somewhere between +performance and consistency. + +[Back to top](#introduction) + +## Single node Kong clusters + +A single Kong node connected to a database (Cassandra or PostgreSQL) creates a +Kong cluster of one node. Any changes applied via the Admin API of this node +will instantly take effect. Example: + +Consider a single Kong node `A`. If we delete a previously registered Service: + +```bash +$ curl -X DELETE http://127.0.0.1:8001/services/test-service +``` + +Then any subsequent request to `A` would instantly return `404 Not Found`, as +the node purged it from its local cache: + +```bash +$ curl -i http://127.0.0.1:8000/test-service +``` + +[Back to top](#introduction) + +## Multiple nodes Kong clusters + +In a cluster of multiple Kong nodes, other nodes connected to the same database +would not instantly be notified that the Service was deleted by node `A`. While +the Service is **not** in the database anymore (it was deleted by node `A`), it is +**still** in node `B`'s memory. + +All nodes perform a periodic background job to synchronize with changes that +may have been triggered by other nodes. The frequency of this job can be +configured via: + +* [db_update_frequency][db_update_frequency] (default: 5 seconds) + +Every `db_update_frequency` seconds, all running Kong nodes will poll the +database for any update, and will purge the relevant entities from their cache +if necessary. + +If we delete a Service from node `A`, this change will not be effective in node +`B` until node `B`s next database poll, which will occur up to +`db_update_frequency` seconds later (though it could happen sooner). + +This makes Kong clusters **eventually consistent**. + +[Back to top](#introduction) + +## What is being cached? + +All of the core entities such as Services, Routes, Plugins, Consumers, Credentials are +cached in memory by Kong and depend on their invalidation via the polling +mechanism to be updated. + +Additionally, Kong also caches **database misses**. This means that if you +configure a Service with no plugin, Kong will cache this information. Example: + +On node `A`, we add a Service and a Route: + +```bash +# node A +$ curl -X POST http://127.0.0.1:8001/services \ + --data "name=example-service" \ + --data "url=http://example.com" + +$ curl -X POST http://127.0.0.1:8001/services/example-service/routes \ + --data "paths[]=/example" +``` + +(Note that we used `/services/example-service/routes` as a shortcut: we +could have used the `/routes` endpoint instead, but then we would need to +pass `service_id` as an argument, with the UUID of the new Service.) + +A request to the Proxy port of both node `A` and `B` will cache this Service, and +the fact that no plugin is configured on it: + +```bash +# node A +$ curl http://127.0.0.1:8000/example +HTTP 200 OK +... +``` + +```bash +# node B +$ curl http://127.0.0.2:8000/example +HTTP 200 OK +... +``` + +Now, say we add a plugin to this Service via node `A`'s Admin API: + +```bash +# node A +$ curl -X POST http://127.0.0.1:8001/services/example-service/plugins \ + --data "name=example-plugin" +``` + +Because this request was issued via node `A`'s Admin API, node `A` will locally +invalidate its cache and on subsequent requests, it will detect that this API +has a plugin configured. + +However, node `B` hasn't run a database poll yet, and still caches that this +API has no plugin to run. It will be so until node `B` runs its database +polling job. + +**Conclusion**: All CRUD operations trigger cache invalidations. Creation +(`POST`, `PUT`) will invalidate cached database misses, and update/deletion +(`PATCH`, `DELETE`) will invalidate cached database hits. + +[Back to top](#introduction) + +## How to configure database caching? + +You can configure three properties in the Kong configuration file, the most +important one being `db_update_frequency`, which determine where your Kong +nodes stand on the performance versus consistency trade-off. + +Kong comes with default values tuned for consistency so that you can +experiment with its clustering capabilities while avoiding surprises. As you +prepare a production setup, you should consider tuning those values to ensure +that your performance constraints are respected. + +### 1. [db_update_frequency][db_update_frequency] (default: 5s) + +This value determines the frequency at which your Kong nodes will be polling +the database for invalidation events. A lower value means that the polling +job will execute more frequently, but that your Kong nodes will keep up +with changes you apply. A higher value means that your Kong nodes will +spend less time running the polling jobs, and will focus on proxying your +traffic. + +**Note**: Changes propagate through the cluster in up to `db_update_frequency` +seconds. + +[Back to top](#introduction) + +### 2. [db_update_propagation][db_update_propagation] (default: 0s) + +If your database itself is eventually consistent (that is, Cassandra), you **must** +configure this value. It is to ensure that the change has time to propagate +across your database nodes. When set, Kong nodes receiving invalidation events +from their polling jobs will delay the purging of their cache for +`db_update_propagation` seconds. + +If a Kong node connected to an eventually consistent database was not delaying +the event handling, it could purge its cache, only to cache the non-updated +value again (because the change hasn't propagated through the database yet)! + +You should set this value to an estimate of the amount of time your database +cluster takes to propagate changes. + +**Note**: When this value is set, changes propagate through the cluster in +up to `db_update_frequency + db_update_propagation` seconds. + +[Back to top](#introduction) + +### 3. [db_cache_ttl][db_cache_ttl] (default: 0s) + +The time (in seconds) for which Kong will cache database entities (both hits +and misses). This Time-To-Live value acts as a safeguard in case a Kong node +misses an invalidation event, to avoid it from running on stale data for too +long. When the TTL is reached, the value will be purged from its cache, and the +next database result will be cached again. + +By default, no data is invalidated based on this TTL (the default value is `0`). +This is usually fine: Kong nodes rely on invalidation events, which are handled +at the db store level (Cassandra/PosgreSQL). If you are concerned that a Kong +node might miss invalidation event for any reason, you should set a TTL. Otherwise +the node might run with a stale value in its cache for an undefined amount of time +until the cache is manually purged, or the node is restarted. + +[Back to top](#introduction) + +### 4. When using Cassandra + +If you use Cassandra as your Kong database, you **must** set +[db_update_propagation][db_update_propagation] to a non-zero value. Since +Cassandra is eventually consistent by nature, this will ensure that Kong nodes +do not prematurely invalidate their cache, only to fetch and catch a +not up-to-date entity again. Kong will present you a warning in logs if you did +not configure this value when using Cassandra. + +Additionally, you might want to configure `cassandra_consistency` to a value +like `QUORUM` or `LOCAL_QUORUM`, to ensure that values being cached by your +Kong nodes are up-to-date values from your database. + +Setting the `cassandra_refresh_frequency` option to `0` is not advised, as a Kong +restart will be required to discover any changes to the Cassandra cluster topology. + +[Back to top](#introduction) + +## Interacting with the cache via the Admin API + +If for some reason, you want to investigate the cached values, or manually +invalidate a value cached by Kong (a cached hit or miss), you can do so via the +Admin API `/cache` endpoint. + +### Inspect a cached value + +**Endpoint** + +
/cache/{cache_key}
+ +**Response** + +If a value with that key is cached: + +``` +HTTP 200 OK +... +{ + ... +} +``` + +Else: + +``` +HTTP 404 Not Found +``` + +**Note**: Retrieving the `cache_key` for each entity being cached by Kong is +currently an undocumented process. Future versions of the Admin API will make +this process easier. + +[Back to top](#introduction) + +### Purge a cached value + +**Endpoint** + +
/cache/{cache_key}
+ +**Response** + +``` +HTTP 204 No Content +... +``` + +**Note**: Retrieving the `cache_key` for each entity being cached by Kong is +currently an undocumented process. Future versions of the Admin API will make +this process easier. + +[Back to top](#introduction) + +### Purge a node's cache + +**Endpoint** + +
/cache
+ +**Response** + +``` +HTTP 204 No Content +``` + +**Note**: Be wary of using this endpoint on a node running in production with a warmed cache. +If the node is receiving a lot of traffic, purging its cache at the same time +will trigger many requests to your database, and could cause a +[dog-pile effect](https://en.wikipedia.org/wiki/Cache_stampede). + +[Back to top](#introduction) + +[db_update_frequency]: /{{page.kong_version}}/configuration/#db_update_frequency +[db_update_propagation]: /{{page.kong_version}}/configuration/#db_update_propagation +[db_cache_ttl]: /{{page.kong_version}}/configuration/#db_cache_ttl diff --git a/app/2.2.x/configuration.md b/app/2.2.x/configuration.md new file mode 100644 index 000000000000..74a020774589 --- /dev/null +++ b/app/2.2.x/configuration.md @@ -0,0 +1,1787 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# the files in https://github.com/Kong/kong/tree/master/autodoc/conf +# +title: Configuration Reference +skip_read_time: true +--- + +## Configuration loading + +Kong comes with a default configuration file that can be found at +`/etc/kong/kong.conf.default` if you installed Kong via one of the official +packages. To start configuring Kong, you can copy this file: + +```bash +$ cp /etc/kong/kong.conf.default /etc/kong/kong.conf +``` + +Kong will operate with default settings should all the values in your +configuration be commented out. Upon starting, Kong looks for several +default locations that might contain a configuration file: + +``` +/etc/kong/kong.conf +/etc/kong.conf +``` + +You can override this behavior by specifying a custom path for your +configuration file using the `-c / --conf` argument in the CLI: + +```bash +$ kong start --conf /path/to/kong.conf +``` + +The configuration format is straightforward: simply uncomment any property +(comments are defined by the `#` character) and modify it to your needs. +Boolean values can be specified as `on`/`off` or `true`/`false` for convenience. + +## Verifying your configuration + +You can verify the integrity of your settings with the `check` command: + +```bash +$ kong check +configuration at is valid +``` + +This command will take into account the environment variables you have +currently set, and will error out in case your settings are invalid. + +Additionally, you can also use the CLI in debug mode to have more insight +as to what properties Kong is being started with: + +```bash +$ kong start -c --vv +2016/08/11 14:53:36 [verbose] no config file found at /etc/kong.conf +2016/08/11 14:53:36 [verbose] no config file found at /etc/kong/kong.conf +2016/08/11 14:53:36 [debug] admin_listen = "0.0.0.0:8001" +2016/08/11 14:53:36 [debug] database = "postgres" +2016/08/11 14:53:36 [debug] log_level = "notice" +[...] +``` + +## Environment variables + +When loading properties out of a configuration file, Kong will also look for +environment variables of the same name. This allows you to fully configure Kong +via environment variables, which is very convenient for container-based +infrastructures, for example. + +To override a setting using an environment variable, declare an environment +variable with the name of the setting, prefixed with `KONG_` and capitalized. + +For example: + +``` +log_level = debug # in kong.conf +``` + +can be overridden with: + +```bash +$ export KONG_LOG_LEVEL=error +``` + +## Injecting Nginx directives + +Tweaking the Nginx configuration of your Kong instances allows you to optimize +its performance for your infrastructure. + +When Kong starts, it builds an Nginx configuration file. You can inject custom +Nginx directives to this file directly via your Kong configuration. + +### Injecting individual Nginx directives + +Any entry added to your `kong.conf` file that is prefixed by `nginx_http_`, +`nginx_proxy_` or `nginx_admin_` will be converted into an equivalent Nginx +directive by removing the prefix and added to the appropriate section of the +Nginx configuration: + +- Entries prefixed with `nginx_http_` will be injected to the overall `http` +block directive. + +- Entries prefixed with `nginx_proxy_` will be injected to the `server` block +directive handling Kong's proxy ports. + +- Entries prefixed with `nginx_admin_` will be injected to the `server` block +directive handling Kong's Admin API ports. + +For example, if you add the following line to your `kong.conf` file: + +``` +nginx_proxy_large_client_header_buffers=16 128k +``` + +it will add the following directive to the proxy `server` block of Kong's +Nginx configuration: + +``` + large_client_header_buffers 16 128k; +``` + +Like any other entry in `kong.conf`, these directives can also be specified +using [environment variables](#environment-variables) as shown above. For +example, if you declare an environment variable like this: + +```bash +$ export KONG_NGINX_HTTP_OUTPUT_BUFFERS="4 64k" +``` + +This will result in the following Nginx directive being added to the `http` +block: + +``` + output_buffers 4 64k; +``` + +As always, be mindful of your shell's quoting rules specifying values +containing spaces. + +For more details on the Nginx configuration file structure and block +directives, see https://nginx.org/en/docs/beginners_guide.html#conf_structure. + +For a list of Nginx directives, see https://nginx.org/en/docs/dirindex.html. +Note however that some directives are dependent of specific Nginx modules, +some of which may not be included with the official builds of Kong. + +### Including files via injected Nginx directives + +For more complex configuration scenarios, such as adding entire new +`server` blocks, you can use the method described above to inject an +`include` directive to the Nginx configuration, pointing to a file +containing your additional Nginx settings. + +For example, if you create a file called `my-server.kong.conf` with +the following contents: + +``` +# custom server +server { + listen 2112; + location / { + # ...more settings... + return 200; + } +} +``` + +You can make the Kong node serve this port by adding the following +entry to your `kong.conf` file: + +``` +nginx_http_include = /path/to/your/my-server.kong.conf +``` + +or, alternatively, by configuring it via an environment variable: + +```bash +$ export KONG_NGINX_HTTP_INCLUDE="/path/to/your/my-server.kong.conf" +``` + +Now, when you start Kong, the `server` section from that file will be added to +that file, meaning that the custom server defined in it will be responding, +alongside the regular Kong ports: + +```bash +$ curl -I http://127.0.0.1:2112 +HTTP/1.1 200 OK +... +``` + +Note that if you use a relative path in an `nginx_http_include` property, that +path will be interpreted relative to the value of the `prefix` property of +your `kong.conf` file (or the value of the `-p` flag of `kong start` if you +used it to override the prefix when starting Kong). + +## Custom Nginx templates & embedding Kong + +For the vast majority of use-cases, using the Nginx directive injection system +explained above should be sufficient for customizing the behavior of Kong's +Nginx instance. This way, you can manage the configuration and tuning of your +Kong node from a single `kong.conf` file (and optionally your own included +files), without having to deal with custom Nginx configuration templates. + +There are two scenarios in which you may want to make use of custom Nginx +configuration templates directly: + +- In the rare occasion that you may need to modify some of Kong's default +Nginx configuration that are not adjustable via its standard `kong.conf` +properties, you can still modify the template used by Kong for producing its +Nginx configuration and launch Kong using your customized template. + +- If you need to embed Kong in an already running OpenResty instance, you +can reuse Kong's generated configuration and include it in your existing +configuration. + +### Custom Nginx templates + +Kong can be started, reloaded and restarted with an `--nginx-conf` argument, +which must specify an Nginx configuration template. Such a template uses the +[Penlight][Penlight] [templating engine][pl.template], which is compiled using +the given Kong configuration, before being dumped in your Kong prefix +directory, moments before starting Nginx. + +The default template can be found at: +https://github.com/kong/kong/tree/master/kong/templates. It is split in two +Nginx configuration files: `nginx.lua` and `nginx_kong.lua`. The former is +minimalistic and includes the latter, which contains everything Kong requires +to run. When `kong start` runs, right before starting Nginx, it copies these +two files into the prefix directory, which looks like so: + +``` +/usr/local/kong +├── nginx-kong.conf +└── nginx.conf +``` + +If you must tweak global settings that are defined by Kong but not adjustable +via the Kong configuration in `kong.conf`, you can inline the contents of the +`nginx_kong.lua` configuration template into a custom template file (in this +example called `custom_nginx.template`) like this: + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{ "{{NGINX_WORKER_PROCESSES" }}}}; # can be set by kong.conf +daemon ${{ "{{NGINX_DAEMON" }}}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; # can be set by kong.conf + +events { + use epoll; # a custom setting + multi_accept on; +} + +http { + + # contents of the nginx_kong.lua template follow: + + resolver ${{ "{{DNS_RESOLVER" }}}} ipv6=off; + charset UTF-8; + error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; + access_log logs/access.log; + + ... # etc +} +``` + +You can then start Kong with: + +```bash +$ kong start -c kong.conf --nginx-conf custom_nginx.template +``` + +## Embedding Kong in OpenResty + +If you are running your own OpenResty servers, you can also easily embed Kong +by including the Kong Nginx sub-configuration using the `include` directive. +If you have an existing Nginx configuration, you can simply include the +Kong-specific portion of the configuration which is output by Kong in a separate +`nginx-kong.conf` file: + +``` +# my_nginx.conf + +# ...your nginx settings... + +http { + include 'nginx-kong.conf'; + + # ...your nginx settings... +} +``` + +You can then start your Nginx instance like so: + +```bash +$ nginx -p /usr/local/openresty -c my_nginx.conf +``` + +and Kong will be running in that instance (as configured in `nginx-kong.conf`). + +## Serving both a website and your APIs from Kong + +A common use case for API providers is to make Kong serve both a website +and the APIs themselves over the Proxy port — `80` or `443` in +production. For example, `https://example.net` (Website) and +`https://example.net/api/v1` (API). + +To achieve this, we cannot simply declare a new virtual server block, +like we did in the previous section. A good solution is to use a custom +Nginx configuration template which inlines `nginx_kong.lua` and adds a new +`location` block serving the website alongside the Kong Proxy `location` +block: + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{ "{{NGINX_WORKER_PROCESSES" }}}}; # can be set by kong.conf +daemon ${{ "{{NGINX_DAEMON" }}}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log logs/error.log ${{ "{{LOG_LEVEL" }}}}; # can be set by kong.conf +events {} + +http { + # here, we inline the contents of nginx_kong.lua + charset UTF-8; + + # any contents until Kong's Proxy server block + ... + + # Kong's Proxy server block + server { + server_name kong; + + # any contents until the location / block + ... + + # here, we declare our custom location serving our website + # (or API portal) which we can optimize for serving static assets + location / { + root /var/www/example.net; + index index.htm index.html; + ... + } + + # Kong's Proxy location / has been changed to /api/v1 + location /api/v1 { + set $upstream_host nil; + set $upstream_scheme nil; + set $upstream_uri nil; + + # Any remaining configuration for the Proxy location + ... + } + } + + # Kong's Admin server block goes below + # ... +} +``` + +## Properties reference + +### General section + +#### prefix + +Working directory. Equivalent to Nginx's prefix path, containing temporary +files and logs. + +Each Kong process must have a separate working directory. + +Default: `/usr/local/kong/` + +--- + +#### log_level + +Log level of the Nginx server. Logs are found at `/logs/error.log`. + +See http://nginx.org/en/docs/ngx_core_module.html#error_log for a list of +accepted values. + +Default: `notice` + +--- + +#### proxy_access_log + +Path for proxy port request access logs. Set this value to `off` to disable +logging proxy requests. + +If this value is a relative path, it will be placed under the `prefix` +location. + +Default: `logs/access.log` + +--- + +#### proxy_error_log + +Path for proxy port request error logs. The granularity of these logs is +adjusted by the `log_level` property. + +Default: `logs/error.log` + +--- + +#### admin_access_log + +Path for Admin API request access logs. Set this value to `off` to disable +logging Admin API requests. + +If this value is a relative path, it will be placed under the `prefix` +location. + +Default: `logs/admin_access.log` + +--- + +#### admin_error_log + +Path for Admin API request error logs. The granularity of these logs is +adjusted by the `log_level` property. + +Default: `logs/error.log` + +--- + +#### status_access_log + +Path for Status API request access logs. The default value of `off` implies +that loggin for this API is disabled by default. + +If this value is a relative path, it will be placed under the `prefix` +location. + +Default: `off` + +--- + +#### status_error_log + +Path for Status API request error logs. The granularity of these logs is +adjusted by the `log_level` property. + +Default: `logs/status_error.log` + +--- + +#### plugins + +Comma-separated list of plugins this node should load. By default, only plugins +bundled in official distributions are loaded via the `bundled` keyword. + +Loading a plugin does not enable it by default, but only instructs Kong to load +its source code, and allows to configure the plugin via the various related +Admin API endpoints. + +The specified name(s) will be substituted as such in the Lua namespace: +`kong.plugins.{name}.*`. + +When the `off` keyword is specified as the only value, no plugins will be +loaded. + +`bundled` and plugin names can be mixed together, as the following examples +suggest: + +- `plugins = bundled,custom-auth,custom-log` will include the bundled plugins + plus two custom ones +- `plugins = custom-auth,custom-log` will *only* include the `custom-auth` and + `custom-log` plugins. +- `plugins = off` will not include any plugins + +**Note:** Kong will not start if some plugins were previously configured (i.e. + +have rows in the database) and are not specified in this list. Before disabling +a plugin, ensure all instances of it are removed before restarting Kong. + +**Note:** Limiting the amount of available plugins can improve P99 latency when +experiencing LRU churning in the database cache (i.e. when the configured +`mem_cache_size`) is full. + +Default: `bundled` + +--- + +#### go_pluginserver_exe + +Path for the go-pluginserver executable, used for running Kong plugins written +in Go. + +Default: `/usr/local/bin/go-pluginserver` + +--- + +#### go_plugins_dir + +Directory for installing Kong plugins written in Go. + +This value can be set to `off`, thus disabling the plugin server and Go plugin +loading. + +Default: `off` + +--- + +#### port_maps + +With this configuration parameter, you can let the Kong to know about the port +from which the packets are forwarded to it. This is fairly common when running +Kong in a containerized or virtualized environment. + +For example, `port_maps=80:8000, 443:8443` instructs Kong that the port 80 is +mapped to 8000 (and the port 443 to 8443), where 8000 and 8443 are the ports +that Kong is listening to. + +This parameter helps Kong set a proper forwarded upstream HTTP request header +or to get the proper forwarded port with the Kong PDK (in case other means +determining it has failed). It changes routing by a destination port to route by +a port from which packets are forwarded to Kong, and similarly it changes the +default plugin log serializer to use the port according to this mapping instead +of reporting the port Kong is listening to. + +Default: none + +--- + +#### anonymous_reports + +Send anonymous usage data such as error stack traces to help improve Kong. + +Default: `on` + +--- + + +### Hybrid Mode section + +#### role + +Use this setting to enable Hybrid Mode, This allows running some Kong nodes in +a control plane role with a database and have them deliver configuration updates +to other nodes running to DB-less running in a Data Plane role. + +Valid values to this setting are: + +- `traditional`: do not use Hybrid Mode. +- `control_plane`: this node runs in a control plane role. It can use a + database and will deliver configuration updates to data plane nodes. +- `data_plane`: this is a data plane node. It runs DB-less and receives + configuration updates from a control plane node. + +Default: `traditional` + +--- + +#### cluster_mtls + +Sets the verification between nodes of the cluster. + +Valid values to this setting are: + +- `shared`: use a shared certificate/key pair specified with the `cluster_cert` + and `cluster_cert_key` settings. Note that CP and DP nodes have to present the + same certificate to establish mTLS connections. +- `pki`: use `cluster_ca_cert`, `cluster_server_name` and `cluster_cert` for + verification. These are different certificates for each DP node, but issued by + a cluster-wide common CA certificate: `cluster_ca_cert`. + +Default: `shared` + +--- + +#### cluster_cert + +Filename of the cluster certificate to use when establishing secure +communication between control and data plane nodes. + +You can use the `kong hybrid` command to generate the certificate/key pair. + +Under `shared` mode, it must be the same for all nodes. Under `pki` mode it +should be a different certificate for each DP node. + +Default: none + +--- + +#### cluster_cert_key + +Filename of the cluster certificate key to use when establishing secure +communication between control and data plane nodes. + +You can use the `kong hybrid` command to generate the certificate/key pair. + +Under `shared` mode, it must be the same for all nodes. Under `pki` mode it +should be a different certificate for each DP node. + +Default: none + +--- + +#### cluster_ca_cert + +The trusted CA certificate file in PEM format used to verify the +`cluster_cert`. + +Required if `cluster_mtls` is set to `pki`, ignored otherwise. + +Default: none + +--- + +#### cluster_server_name + +The server name used in the SNI of the TLS connection from a DP node to a CP +node. + +Must match the Common Name (CN) or Subject Alternative Name (SAN) found in the +CP certificate. + +If `cluster_mtls` is set to `shared`, this setting is ignored and +`kong_clustering` is used. + +Default: none + +--- + +#### cluster_control_plane + +To be used by data plane nodes only: address of the control plane node from +which configuration updates will be fetched, in `host:port` format. + +Default: none + +--- + +#### cluster_listen + +Comma-separated list of addresses and ports on which the cluster control plane +server should listen for data plane connections. + +The cluster communication port of the control plane must be accessible by all +the data planes within the same cluster. This port is mTLS protected to ensure +end-to-end security and integrity. + +This setting has no effect if `role` is not set to `control_plane`. + +Default: `0.0.0.0:8005` + +--- + +#### cluster_data_plane_purge_delay + +How many seconds must pass from the time a DP node becomes offline to the time +its entry gets removed from the database, as returned by the +/clustering/data_planes Admin API endpoint. + +This is to prevent the cluster data plane table from growing indefinitely. The +default is set to 14 days. That is, if CP haven't heard from a DP for 14 days, +its entry will be removed. + +Default: `1209600` + +--- + + +### NGINX section + +#### proxy_listen + +Comma-separated list of addresses and ports on which the proxy server should +listen for HTTP/HTTPS traffic. + +The proxy server is the public entry point of Kong, which proxies traffic from +your consumers to your backend services. This value accepts IPv4, IPv6, and +hostnames. + +Some suffixes can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. +- `http2` will allow for clients to open HTTP/2 connections to Kong's proxy + server. +- `proxy_protocol` will enable usage of the PROXY protocol for a given + address/port. +- `deferred` instructs to use a deferred accept on Linux (the TCP_DEFER_ACCEPT + socket option). +- `bind` instructs to make a separate bind() call for a given address:port + pair. +- `reuseport` instructs to create an individual listening socket for each + worker process allowing the Kernel to better distribute incoming connections + between worker processes +- `backlog=N` sets the maximum length for the queue of pending TCP connections. + This number should not be too small in order to prevent clients seeing + "Connection refused" error connecting to a busy Kong instance. **Note:** on + Linux, this value is limited by the setting of `net.core.somaxconn` Kernel + parameter. In order for the larger `backlog` set here to take effect it is + necessary to raise `net.core.somaxconn` at the same time to match or exceed + the `backlog` number set. + +This value can be set to `off`, thus disabling the HTTP/HTTPS proxy port for +this node. + +If stream_listen is also set to `off`, this enables 'control-plane' mode for +this node (in which all traffic proxying capabilities are disabled). This node +can then be used only to configure a cluster of Kong nodes connected to the same +datastore. + +Example: `proxy_listen = 0.0.0.0:443 ssl, 0.0.0.0:444 http2 ssl` + +See http://nginx.org/en/docs/http/ngx_http_core_module.html#listen for a +description of the accepted formats for this and other `*_listen` values. + +See https://www.nginx.com/resources/admin-guide/proxy-protocol/ for more +details about the `proxy_protocol` parameter. + +Not all `*_listen` values accept all formats specified in nginx's +documentation. + +Default: `0.0.0.0:8000 reuseport backlog=16384, 0.0.0.0:8443 http2 ssl reuseport backlog=16384` + +--- + +#### stream_listen + +Comma-separated list of addresses and ports on which the stream mode should +listen. + +This value accepts IPv4, IPv6, and hostnames. + +Some suffixes can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. +- `udp` defines the port as UDP instead of the default TCP. +- `proxy_protocol` will enable usage of the PROXY protocol for a given + address/port. +- `bind` instructs to make a separate bind() call for a given address:port + pair. +- `reuseport` instructs to create an individual listening socket for each + worker process allowing the Kernel to better distribute incoming connections + between worker processes +- `backlog=N` sets the maximum length for the queue of pending TCP connections. + This number should not be too small in order to prevent clients seeing + "Connection refused" error connecting to a busy Kong instance. **Note:** on + Linux, this value is limited by the setting of `net.core.somaxconn` Kernel + parameter. In order for the larger `backlog` set here to take effect it is + necessary to raise `net.core.somaxconn` at the same time to match or exceed + the `backlog` number set. + +**Note:** The `ssl` suffix is not supported, and each address/port will accept +TCP with or without TLS enabled. + +Examples: + +``` +stream_listen = 127.0.0.1:7000 reuseport backlog=16384 +stream_listen = 0.0.0.0:989 reuseport backlog=65536, 0.0.0.0:20 +stream_listen = [::1]:1234 backlog=16384 +``` + +By default this value is set to `off`, thus disabling the stream proxy port for +this node. + +See http://nginx.org/en/docs/stream/ngx_stream_core_module.html#listen for a +description of the formats that Kong might accept in stream_listen. + +Default: `off` + +--- + +#### admin_listen + +Comma-separated list of addresses and ports on which the Admin interface should +listen. + +The Admin interface is the API allowing you to configure and manage Kong. + +Access to this interface should be *restricted* to Kong administrators *only*. +This value accepts IPv4, IPv6, and hostnames. + +Some suffixes can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. +- `http2` will allow for clients to open HTTP/2 connections to Kong's proxy + server. +- `proxy_protocol` will enable usage of the PROXY protocol for a given + address/port. +- `deferred` instructs to use a deferred accept on Linux (the TCP_DEFER_ACCEPT + socket option). +- `bind` instructs to make a separate bind() call for a given address:port + pair. +- `reuseport` instructs to create an individual listening socket for each + worker process allowing the Kernel to better distribute incoming connections + between worker processes +- `backlog=N` sets the maximum length for the queue of pending TCP connections. + This number should not be too small in order to prevent clients seeing + "Connection refused" error connecting to a busy Kong instance. **Note:** on + Linux, this value is limited by the setting of `net.core.somaxconn` Kernel + parameter. In order for the larger `backlog` set here to take effect it is + necessary to raise `net.core.somaxconn` at the same time to match or exceed + the `backlog` number set. + +This value can be set to `off`, thus disabling the Admin interface for this +node, enabling a 'data-plane' mode (without configuration capabilities) pulling +its configuration changes from the database. + +Example: `admin_listen = 127.0.0.1:8444 http2 ssl` + +Default: `127.0.0.1:8001 reuseport backlog=16384, 127.0.0.1:8444 http2 ssl reuseport backlog=16384` + +--- + +#### status_listen + +Comma-separated list of addresses and ports on which the Status API should +listen. + +The Status API is a read-only endpoint allowing monitoring tools to retrieve +metrics, healthiness, and other non-sensitive information of the current Kong +node. + +The following suffix can be specified for each pair: + +- `ssl` will require that all connections made through a particular + address/port be made with TLS enabled. + +This value can be set to `off`, disabling the Status API for this node. + +Example: `status_listen = 0.0.0.0:8100` + +Default: `off` + +--- + +#### nginx_user + +Defines user and group credentials used by worker processes. If group is +omitted, a group whose name equals that of user is used. + +Example: `nginx_user = nginx www` + +Default: `nobody nobody` + +--- + +#### nginx_worker_processes + +Determines the number of worker processes spawned by Nginx. + +See http://nginx.org/en/docs/ngx_core_module.html#worker_processes for detailed +usage of the equivalent Nginx directive and a description of accepted values. + +Default: `auto` + +--- + +#### nginx_daemon + +Determines whether Nginx will run as a daemon or as a foreground process. +Mainly useful for development or when running Kong inside a Docker environment. + +See http://nginx.org/en/docs/ngx_core_module.html#daemon. + +Default: `on` + +--- + +#### mem_cache_size + +Size of each of the two in-memory caches for database entities. The accepted +units are `k` and `m`, with a minimum recommended value of a few MBs. + +**Note**: As this option controls the size of two different cache entries, the +total memory Kong uses to cache entities might be double this value. + +Default: `128m` + +--- + +#### ssl_cipher_suite + +Defines the TLS ciphers served by Nginx. + +Accepted values are `modern`, `intermediate`, `old`, or `custom`. + +See https://wiki.mozilla.org/Security/Server_Side_TLS for detailed descriptions +of each cipher suite. + +Default: `intermediate` + +--- + +#### ssl_ciphers + +Defines a custom list of TLS ciphers to be served by Nginx. This list must +conform to the pattern defined by `openssl ciphers`. + +This value is ignored if `ssl_cipher_suite` is not `custom`. + +Default: none + +--- + +#### ssl_protocols + +Enables the specified protocols for client-side connections. The set of +supported protocol versions also depends on the version of OpenSSL Kong was +built with. This value is ignored if `ssl_cipher_suite` is not `custom`. + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols + +Default: `TLSv1.1 TLSv1.2 TLSv1.3` + +--- + +#### ssl_prefer_server_ciphers + +Specifies that server ciphers should be preferred over client ciphers when +using the SSLv3 and TLS protocols. This value is ignored if `ssl_cipher_suite` +is not `custom`. + +See +http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers + +Default: `on` + +--- + +#### ssl_session_tickets + +Enables or disables session resumption through TLS session tickets. This has no +impact when used with TLSv1.3. + +Kong enables this by default for performance reasons, but it has security +implications: https://github.com/mozilla/server-side-tls/issues/135 + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets + +Default: `on` + +--- + +#### ssl_session_timeout + +Specifies a time during which a client may reuse the session parameters. See +the rationale: https://github.com/mozilla/server-side-tls/issues/198 + +See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout + +Default: `1d` + +--- + +#### ssl_cert + +The absolute path to the SSL certificate for `proxy_listen` values with SSL +enabled. + +Default: none + +--- + +#### ssl_cert_key + +The absolute path to the SSL key for `proxy_listen` values with SSL enabled. + +Default: none + +--- + +#### client_ssl + +Determines if Nginx should send client-side SSL certificates when proxying +requests. + +Default: `off` + +--- + +#### client_ssl_cert + +If `client_ssl` is enabled, the absolute path to the client SSL certificate for +the `proxy_ssl_certificate` directive. Note that this value is statically +defined on the node, and currently cannot be configured on a per-API basis. + +Default: none + +--- + +#### client_ssl_cert_key + +If `client_ssl` is enabled, the absolute path to the client SSL key for the +`proxy_ssl_certificate_key` address. Note this value is statically defined on +the node, and currently cannot be configured on a per-API basis. + +Default: none + +--- + +#### admin_ssl_cert + +The absolute path to the SSL certificate for `admin_listen` values with SSL +enabled. + +Default: none + +--- + +#### admin_ssl_cert_key + +The absolute path to the SSL key for `admin_listen` values with SSL enabled. + +Default: none + +--- + +#### status_ssl_cert + +The absolute path to the SSL certificate for `status_listen` values with SSL +enabled. + +Default: none + +--- + +#### status_ssl_cert_key + +The absolute path to the SSL key for `status_listen` values with SSL enabled. + +Default: none + +--- + +#### headers + +Comma-separated list of headers Kong should inject in client responses. + +Accepted values are: + +- `Server`: Injects `Server: kong/x.y.z` on Kong-produced response (e.g. Admin + API, rejected requests from auth plugin). +- `Via`: Injects `Via: kong/x.y.z` for successfully proxied requests. +- `X-Kong-Proxy-Latency`: Time taken (in milliseconds) by Kong to process a + request and run all plugins before proxying the request upstream. +- `X-Kong-Response-Latency`: time taken (in millisecond) by Kong to produce a + response in case of e.g. plugin short-circuiting the request, or in in case of + an error. +- `X-Kong-Upstream-Latency`: Time taken (in milliseconds) by the upstream + service to send response headers. +- `X-Kong-Admin-Latency`: Time taken (in milliseconds) by Kong to process an + Admin API request. +- `X-Kong-Upstream-Status`: The HTTP status code returned by the upstream + service. This is particularly useful for clients to distinguish upstream + statuses if the response is rewritten by a plugin. +- `server_tokens`: Same as specifying both `Server` and `Via`. +- `latency_tokens`: Same as specifying `X-Kong-Proxy-Latency`, + `X-Kong-Response-Latency`, `X-Kong-Admin-Latency` and + `X-Kong-Upstream-Latency` + +In addition to those, this value can be set to `off`, which prevents Kong from +injecting any of the above headers. Note that this does not prevent plugins from +injecting headers of their own. + +Example: `headers = via, latency_tokens` + +Default: `server_tokens, latency_tokens` + +--- + +#### trusted_ips + +Defines trusted IP addresses blocks that are known to send correct +`X-Forwarded-*` headers. + +Requests from trusted IPs make Kong forward their `X-Forwarded-*` headers +upstream. + +Non-trusted requests make Kong insert its own `X-Forwarded-*` headers. + +This property also sets the `set_real_ip_from` directive(s) in the Nginx +configuration. It accepts the same type of values (CIDR blocks) but as a +comma-separated list. + +To trust *all* /!\ IPs, set this value to `0.0.0.0/0,::/0`. + +If the special value `unix:` is specified, all UNIX-domain sockets will be +trusted. + +See http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from +for examples of accepted values. + +Default: none + +--- + +#### real_ip_header + +Defines the request header field whose value will be used to replace the client +address. + +This value sets the `ngx_http_realip_module` directive of the same name in the +Nginx configuration. + +If this value receives `proxy_protocol`: + +- at least one of the `proxy_listen` entries must have the `proxy_protocol` + flag enabled. +- the `proxy_protocol` parameter will be appended to the `listen` directive of + the Nginx template. + +See http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header +for a description of this directive. + +Default: `X-Real-IP` + +--- + +#### real_ip_recursive + +This value sets the `ngx_http_realip_module` directive of the same name in the +Nginx configuration. + +See http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive +for a description of this directive. + +Default: `off` + +--- + +#### error_default_type + +Default MIME type to use when the request `Accept` header is missing and Nginx +is returning an error for the request. + +Accepted values are `text/plain`, `text/html`, `application/json`, and +`application/xml`. + +Default: `text/plain` + +--- + +#### upstream_keepalive_pool_size + +Sets the default size of the upstream keepalive connection pools. + +Upstream keepalive connection pools are segmented by the `dst ip/dst port/SNI` +attributes of a connection. + +A value of `0` will disable upstream keepalive connections by default, forcing +each upstream request to open a new connection. + +Default: `60` + +--- + +#### upstream_keepalive_max_requests + +Sets the default maximum number of requests than can be proxied upstream +through one keepalive connection. + +After the maximum number of requests is reached, the connection will be closed. + +A value of `0` will disable this behavior, and a keepalive connection can be +used to proxy an indefinite number of requests. + +Default: `100` + +--- + +#### upstream_keepalive_idle_timeout + +Sets the default timeout (in seconds) for which an upstream keepalive +connection should be kept open. When the timeout is reached while the connection +has not been reused, it will be closed. + +A value of `0` will disable this behavior, and an idle keepalive connection may +be kept open indefinitely. + +Default: `60` + +--- + + +### NGINX Injected Directives section + +Nginx directives can be dynamically injected in the runtime nginx.conf file +without requiring a custom Nginx configuration template. + +All configuration properties respecting the naming scheme +`nginx__` will result in `` being injected in +the Nginx configuration block corresponding to the property's ``. + +Example: `nginx_proxy_large_client_header_buffers = 8 24k` + +Will inject the following directive in Kong's proxy `server {}` block: + +`large_client_header_buffers 8 24k;` + +The following namespaces are supported: + +- `nginx_main_`: Injects `` in Kong's configuration + `main` context. +- `nginx_events_`: Injects `` in Kong's `events {}` + block. +- `nginx_http_`: Injects `` in Kong's `http {}` block. +- `nginx_proxy_`: Injects `` in Kong's proxy `server {}` + block. +- `nginx_upstream_`: Injects `` in Kong's proxy `upstream + {}` block. +- `nginx_admin_`: Injects `` in Kong's Admin API `server + {}` block. +- `nginx_status_`: Injects `` in Kong's Status API + `server {}` block (only effective if `status_listen` is enabled). +- `nginx_stream_`: Injects `` in Kong's stream module + `stream {}` block (only effective if `stream_listen` is enabled). +- `nginx_sproxy_`: Injects `` in Kong's stream module + `server {}` block (only effective if `stream_listen` is enabled). +- `nginx_supstream_`: Injects `` in Kong's stream module + `upstream {}` block. + +As with other configuration properties, Nginx directives can be injected via +environment variables when capitalized and prefixed with `KONG_`. + +Example: `KONG_NGINX_HTTP_SSL_PROTOCOLS` -> `nginx_http_ssl_protocols` + +Will inject the following directive in Kong's `http {}` block: + +`ssl_protocols ;` + +If different sets of protocols are desired between the proxy and Admin API +server, you may specify `nginx_proxy_ssl_protocols` and/or +`nginx_admin_ssl_protocols`, both of which taking precedence over the `http {}` +block. + +--- + +#### nginx_main_worker_rlimit_nofile + +Changes the limit on the maximum number of open files for worker processes. + +The special and default value of `auto` sets this value to `ulimit -n` with the +upper bound limited to 16384 as a measure to protect against excess memory use. + +See http://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile + +Default: `auto` + +--- + +#### nginx_events_worker_connections + +Sets the maximum number of simultaneous connections that can be opened by a +worker process. + +The special and default value of `auto` sets this value to `ulimit -n` with the +upper bound limited to 16384 as a measure to protect against excess memory use. + +See http://nginx.org/en/docs/ngx_core_module.html#worker_connections + +Default: `auto` + +--- + +#### nginx_http_client_header_buffer_size + +Sets buffer size for reading the client request headers. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size + +Default: `1k` + +--- + +#### nginx_http_large_client_header_buffers + +Sets the maximum number and size of buffers used for reading large clients +requests headers. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers + +Default: `4 8k` + +--- + +#### nginx_http_client_max_body_size + +Defines the maximum request body size allowed by requests proxied by Kong, +specified in the Content-Length request header. If a request exceeds this limit, +Kong will respond with a 413 (Request Entity Too Large). Setting this value to 0 +disables checking the request body size. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size + +Default: `0` + +--- + +#### nginx_http_client_body_buffer_size + +Defines the buffer size for reading the request body. If the client request +body is larger than this value, the body will be buffered to disk. Note that +when the body is buffered to disk, Kong plugins that access or manipulate the +request body may not work, so it is advisable to set this value as high as +possible (e.g., set it as high as `client_max_body_size` to force request bodies +to be kept in memory). Do note that high-concurrency environments will require +significant memory allocations to process many concurrent large request bodies. + +See +http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size + +Default: `8k` + +--- + + +### Datastore section + +Kong can run with a database to store coordinated data between Kong nodes in a +cluster, or without a database, where each node stores its information +independently in memory. + +When using a database, Kong will store data for all its entities (such as +Routes, Services, Consumers, and Plugins) in either Cassandra or PostgreSQL, and +all Kong nodes belonging to the same cluster must connect themselves to the same +database. + +Kong supports the following database versions: + +- **PostgreSQL**: 9.5 and above. +- **Cassandra**: 2.2 and above. + +When not using a database, Kong is said to be in "DB-less mode": it will keep +its entities in memory, and each node needs to have this data entered via a +declarative configuration file, which can be specified through the +`declarative_config` property, or via the Admin API using the `/config` +endpoint. + +When using Postgres as the backend storage, you can optionally enable Kong to +serve read queries from a separate database instance. + +When the number of proxies is large, this can greatly reduce the load on the +main Postgres instance and achieve better scalability. It may also reduce the +latency jitter if the Kong proxy node's latency to the main Postgres instance is +high. + +The read-only Postgres instance only serves read queries and write queries +still goes to the main connection. The read-only Postgres instance can be +eventually consistent while replicating changes from the main instance. + +At least the `pg_ro_host` config is needed to enable this feature. + +By default, all other database config for the read-only connection are +inherited from the corresponding main connection config described above but may +be optionally overwritten explicitly using the `pg_ro_*` config below. + +--- + +#### database + +Determines which of PostgreSQL or Cassandra this node will use as its +datastore. + +Accepted values are `postgres`, `cassandra`, and `off`. + +Default: `postgres` + +--- + + +#### Postgres settings + +name | description | default +-------|--------------|---------- +**pg_host** | Host of the Postgres server. | `127.0.0.1` +**pg_port** | Port of the Postgres server. | `5432` +**pg_timeout** | Defines the timeout (in ms), for connecting, reading and writing. | `5000` +**pg_user** | Postgres user. | `kong` +**pg_password** | Postgres user's password. | none +**pg_database** | The database name to connect to. | `kong` +**pg_schema** | The database schema to use. If unspecified, Kong will respect the `search_path` value of your PostgreSQL instance. | none +**pg_ssl** | Toggles client-server TLS connections between Kong and PostgreSQL. | `off` +**pg_ssl_verify** | Toggles server certificate verification if `pg_ssl` is enabled. See the `lua_ssl_trusted_certificate` setting to specify a certificate authority. | `off` +**pg_max_concurrent_queries** | Sets the maximum number of concurrent queries that can be executing at any given time. This limit is enforced per worker process; the total number of concurrent queries for this node will be will be: `pg_max_concurrent_queries * nginx_worker_processes`. The default value of 0 removes this concurrency limitation. | `0` +**pg_semaphore_timeout** | Defines the timeout (in ms) after which PostgreSQL query semaphore resource acquisition attempts will fail. Such failures will generally result in the associated proxy or Admin API request failing with an HTTP 500 status code. Detailed discussion of this behavior is available in the online documentation. | `60000` +**pg_ro_host** | Same as `pg_host`, but for the read-only connection. **Note:** Refer to the documentation section above for detailed usage. | none +**pg_ro_port** | Same as `pg_port`, but for the read-only connection. | `` +**pg_ro_timeout** | Same as `pg_timeout`, but for the read-only connection. | `` +**pg_ro_user** | Same as `pg_user`, but for the read-only connection. | `` +**pg_ro_password** | Same as `pg_password`, but for the read-only connection. | `` +**pg_ro_database** | Same as `pg_database`, but for the read-only connection. | `` +**pg_ro_schema** | Same as `pg_schema`, but for the read-only connection. | `` +**pg_ro_ssl** | Same as `pg_ssl`, but for the read-only connection. | `` +**pg_ro_ssl_verify** | Same as `pg_ssl_verify`, but for the read-only connection. | `` +**pg_ro_max_concurrent_queries** | Same as `pg_max_concurrent_queries`, but for the read-only connection. Note: read-only concurrency is not shared with the main (read-write) connection. | `` +**pg_ro_semaphore_timeout** | Same as `pg_semaphore_timeout`, but for the read-only connection. | `` + +#### Cassandra settings + +name | description | default +-------|--------------|---------- +**cassandra_contact_points** | A comma-separated list of contact points to your cluster. You may specify IP addresses or hostnames. Note that the port component of SRV records will be ignored in favor of `cassandra_port`. When connecting to a multi-DC cluster, ensure that contact points from the local datacenter are specified first in this list. | `127.0.0.1` +**cassandra_port** | The port on which your nodes are listening on. All your nodes and contact points must listen on the same port. Will be created if it doesn't exist. | `9042` +**cassandra_keyspace** | The keyspace to use in your cluster. | `kong` +**cassandra_write_consistency** | Consistency setting to use when writing to the Cassandra cluster. | `ONE` +**cassandra_read_consistency** | Consistency setting to use when reading from the Cassandra cluster. | `ONE` +**cassandra_timeout** | Defines the timeout (in ms) for reading and writing. | `5000` +**cassandra_ssl** | Toggles client-to-node TLS connections between Kong and Cassandra. | `off` +**cassandra_ssl_verify** | Toggles server certificate verification if `cassandra_ssl` is enabled. See the `lua_ssl_trusted_certificate` setting to specify a certificate authority. | `off` +**cassandra_username** | Username when using the `PasswordAuthenticator` scheme. | `kong` +**cassandra_password** | Password when using the `PasswordAuthenticator` scheme. | none +**cassandra_lb_policy** | Load balancing policy to use when distributing queries across your Cassandra cluster. Accepted values are: `RoundRobin`, `RequestRoundRobin`, `DCAwareRoundRobin`, and `RequestDCAwareRoundRobin`. Policies prefixed with "Request" make efficient use of established connections throughout the same request. Prefer "DCAware" policies if and only if you are using a multi-datacenter cluster. | `RequestRoundRobin` +**cassandra_local_datacenter** | When using the `DCAwareRoundRobin` or `RequestDCAwareRoundRobin` load balancing policy, you must specify the name of the local (closest) datacenter for this Kong node. | none +**cassandra_refresh_frequency** | Frequency (in seconds) at which the cluster topology will be checked for new or decommissioned nodes. A value of `0` will disable this check, and the cluster topology will never be refreshed. | `60` +**cassandra_repl_strategy** | When migrating for the first time, Kong will use this setting to create your keyspace. Accepted values are `SimpleStrategy` and `NetworkTopologyStrategy`. | `SimpleStrategy` +**cassandra_repl_factor** | When migrating for the first time, Kong will create the keyspace with this replication factor when using the `SimpleStrategy`. | `1` +**cassandra_data_centers** | When migrating for the first time, will use this setting when using the `NetworkTopologyStrategy`. The format is a comma-separated list made of `:`. | `dc1:2,dc2:3` +**cassandra_schema_consensus_timeout** | Defines the timeout (in ms) for the waiting period to reach a schema consensus between your Cassandra nodes. This value is only used during migrations. | `10000` + +#### declarative_config + +The path to the declarative configuration file which holds the specification of +all entities (Routes, Services, Consumers, etc.) to be used when the `database` +is set to `off`. + +Entities are stored in Kong's in-memory cache, so you must ensure that enough +memory is allocated to it via the `mem_cache_size` property. You must also +ensure that items in the cache never expire, which means that `db_cache_ttl` +should preserve its default value of 0. + +Default: none + +--- + + +### Datastore Cache section + +In order to avoid unnecessary communication with the datastore, Kong caches +entities (such as APIs, Consumers, Credentials...) for a configurable period of +time. It also handles invalidations if such an entity is updated. + +This section allows for configuring the behavior of Kong regarding the caching +of such configuration entities. + +--- + +#### db_update_frequency + +Frequency (in seconds) at which to check for updated entities with the +datastore. + +When a node creates, updates, or deletes an entity via the Admin API, other +nodes need to wait for the next poll (configured by this value) to eventually +purge the old cached entity and start using the new one. + +Default: `5` + +--- + +#### db_update_propagation + +Time (in seconds) taken for an entity in the datastore to be propagated to +replica nodes of another datacenter. + +When in a distributed environment such as a multi-datacenter Cassandra cluster, +this value should be the maximum number of seconds taken by Cassandra to +propagate a row to other datacenters. + +When set, this property will increase the time taken by Kong to propagate the +change of an entity. + +Single-datacenter setups or PostgreSQL servers should suffer no such delays, +and this value can be safely set to 0. + +Default: `0` + +--- + +#### db_cache_ttl + +Time-to-live (in seconds) of an entity from the datastore when cached by this +node. + +Database misses (no entity) are also cached according to this setting if you do +not configure `db_cache_neg_ttl`. + +If set to 0 (default), such cached entities or misses never expire. + +Default: `0` + +--- + +#### db_cache_neg_ttl + +Time-to-live (in seconds) of a datastore miss (no entity). + +If not specified (default), `db_cache_ttl` value will be used instead. + +If set to 0, misses will never expire. + +Default: none + +--- + +#### db_resurrect_ttl + +Time (in seconds) for which stale entities from the datastore should be +resurrected for when they cannot be refreshed (e.g., the datastore is +unreachable). When this TTL expires, a new attempt to refresh the stale entities +will be made. + +Default: `30` + +--- + +#### db_cache_warmup_entities + +Entities to be pre-loaded from the datastore into the in-memory cache at Kong +start-up. + +This speeds up the first access of endpoints that use the given entities. + +When the `services` entity is configured for warmup, the DNS entries for values +in its `host` attribute are pre-resolved asynchronously as well. + +Cache size set in `mem_cache_size` should be set to a value large enough to +hold all instances of the specified entities. + +If the size is insufficient, Kong will log a warning. + +Default: `services, plugins` + +--- + + +### DNS Resolver section + +By default, the DNS resolver will use the standard configuration files +`/etc/hosts` and `/etc/resolv.conf`. The settings in the latter file will be +overridden by the environment variables `LOCALDOMAIN` and `RES_OPTIONS` if they +have been set. + +Kong will resolve hostnames as either `SRV` or `A` records (in that order, and +`CNAME` records will be dereferenced in the process). + +In case a name was resolved as an `SRV` record it will also override any given +port number by the `port` field contents received from the DNS server. + +The DNS options `SEARCH` and `NDOTS` (from the `/etc/resolv.conf` file) will be +used to expand short names to fully qualified ones. So it will first try the +entire `SEARCH` list for the `SRV` type, if that fails it will try the `SEARCH` +list for `A`, etc. + +For the duration of the `ttl`, the internal DNS resolver will loadbalance each +request it gets over the entries in the DNS record. For `SRV` records the +`weight` fields will be honored, but it will only use the lowest `priority` +field entries in the record. + +--- + +#### dns_resolver + +Comma separated list of nameservers, each entry in `ip[:port]` format to be +used by Kong. If not specified the nameservers in the local `resolv.conf` file +will be used. + +Port defaults to 53 if omitted. Accepts both IPv4 and IPv6 addresses. + +Default: none + +--- + +#### dns_hostsfile + +The hosts file to use. This file is read once and its content is static in +memory. + +To read the file again after modifying it, Kong must be reloaded. + +Default: `/etc/hosts` + +--- + +#### dns_order + +The order in which to resolve different record types. The `LAST` type means the +type of the last successful lookup (for the specified name). The format is a +(case insensitive) comma separated list. + +Default: `LAST,SRV,A,CNAME` + +--- + +#### dns_valid_ttl + +By default, DNS records are cached using the TTL value of a response. If this +property receives a value (in seconds), it will override the TTL for all +records. + +Default: none + +--- + +#### dns_stale_ttl + +Defines, in seconds, how long a record will remain in cache past its TTL. This +value will be used while the new DNS record is fetched in the background. + +Stale data will be used from expiry of a record until either the refresh query +completes, or the `dns_stale_ttl` number of seconds have passed. + +Default: `4` + +--- + +#### dns_not_found_ttl + +TTL in seconds for empty DNS responses and "(3) name error" responses. + +Default: `30` + +--- + +#### dns_error_ttl + +TTL in seconds for error responses. + +Default: `1` + +--- + +#### dns_no_sync + +If enabled, then upon a cache-miss every request will trigger its own dns +query. + +When disabled multiple requests for the same name/type will be synchronised to +a single query. + +Default: `off` + +--- + + +### Tuning & Behavior section + +#### worker_consistency + +Defines whether this node should rebuild its state synchronously or +asynchronously (the balancers and the router are rebuilt on updates that affects +them, e.g., updates to Routes, Services or Upstreams, via the Admin API or +loading a declarative configuration file). + +Accepted values are: + +- `strict`: the router will be rebuilt synchronously, causing incoming requests + to be delayed until the rebuild is finished. +- `eventual`: the router will be rebuilt asynchronously via a recurring + background job running every second inside of each worker. + +Note that `strict` ensures that all workers of a given node will always proxy +requests with an identical router, but that increased long tail latency can be +observed if frequent Routes and Services updates are expected. + +Using `eventual` will help preventing long tail latency issues in such cases, +but may cause workers to route requests differently for a short period of time +after Routes and Services updates. + +Default: `strict` + +--- + +#### worker_state_update_frequency + +Defines how often the worker state changes are checked with a background job. +When a change is detected, a new router or balancer will be built, as needed. +Raising this value will decrease the load on database servers and result in less +jitter in proxy latency, but it might take more time to propagate changes to +each individual worker. + +Default: `5` + +--- + + +### Development & Miscellaneous section + +Additional settings inherited from lua-nginx-module allowing for more +flexibility and advanced usage. + +See the lua-nginx-module documentation for more information: +https://github.com/openresty/lua-nginx-module + +--- + +#### lua_ssl_trusted_certificate + +Comma-separated list of paths to certificate authority files for Lua cosockets +in PEM format. + +The special value `system` attempts to search for the "usual default" provided +by each distro, according to an arbitrary heuristic. In the current +implementation, The following pathnames will be tested in order, and the first +one found will be used: + +* /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu/Gentoo) * +/etc/pki/tls/certs/ca-bundle.crt (Fedora/RHEL 6) * /etc/ssl/ca-bundle.pem +(OpenSUSE) * /etc/pki/tls/cacert.pem (OpenELEC) * +/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (CentOS/RHEL 7) * +/etc/ssl/cert.pem (OpenBSD, Alpine) + +If no file is found on any of these paths, an error will be raised. + +`system` can be used by itself or in conjunction with other CA filepaths. + +When `pg_ssl_verify` or `cassandra_ssl_verify` are enabled, these certificate +authority files will be used for verifying Kong's database connections. + +See https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate + +Default: none + +--- + +#### lua_ssl_verify_depth + +Sets the verification depth in the server certificates chain used by Lua +cosockets, set by `lua_ssl_trusted_certificate`. + +This includes the certificates configured for Kong's database connections. + +See https://github.com/openresty/lua-nginx-module#lua_ssl_verify_depth + +Default: `1` + +--- + +#### lua_package_path + +Sets the Lua module search path (LUA_PATH). Useful when developing or using +custom plugins not stored in the default search path. + +See https://github.com/openresty/lua-nginx-module#lua_package_path + +Default: `./?.lua;./?/init.lua;` + +--- + +#### lua_package_cpath + +Sets the Lua C module search path (LUA_CPATH). + +See https://github.com/openresty/lua-nginx-module#lua_package_cpath + +Default: none + +--- + +#### lua_socket_pool_size + +Specifies the size limit for every cosocket connection pool associated with +every remote server. + +See https://github.com/openresty/lua-nginx-module#lua_socket_pool_size + +Default: `30` + +--- + + + +[Penlight]: http://stevedonovan.github.io/Penlight/api/index.html +[pl.template]: http://stevedonovan.github.io/Penlight/api/libraries/pl.template.html diff --git a/app/2.2.x/db-less-admin-api.md b/app/2.2.x/db-less-admin-api.md new file mode 100644 index 000000000000..3ab166c094ab --- /dev/null +++ b/app/2.2.x/db-less-admin-api.md @@ -0,0 +1,2270 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/blob/master/scripts/autodoc/admin-api/generate.lua +# or its associated files instead. +# +title: Admin API for DB-less Mode +skip_read_time: true +toc: false + +service_body: | + Attributes | Description + ---:| --- + `name`
*optional* | The Service name. + `retries`
*optional* | The number of retries to execute upon failure to proxy. Default: `5`. + `protocol` | The protocol used to communicate with the upstream. Accepted values are: `"grpc"`, `"grpcs"`, `"http"`, `"https"`, `"tcp"`, `"tls"`, `"udp"`. Default: `"http"`. + `host` | The host of the upstream server. + `port` | The upstream server port. Default: `80`. + `path`
*optional* | The path to be used in requests to the upstream server. + `connect_timeout`
*optional* | The timeout in milliseconds for establishing a connection to the upstream server. Default: `60000`. + `write_timeout`
*optional* | The timeout in milliseconds between two successive write operations for transmitting a request to the upstream server. Default: `60000`. + `read_timeout`
*optional* | The timeout in milliseconds between two successive read operations for transmitting a request to the upstream server. Default: `60000`. + `tags`
*optional* | An optional set of strings associated with the Service for grouping and filtering. + `client_certificate`
*optional* | Certificate to be used as client certificate while TLS handshaking to the upstream server. With form-encoded, the notation is `client_certificate.id=`. With JSON, use "`"client_certificate":{"id":""}`. + `tls_verify`
*optional* | Whether to enable verification of upstream server TLS certificate. If set to `null`, then the Nginx default is respected. + `tls_verify_depth`
*optional* | Maximum depth of chain while verifying Upstream server's TLS certificate. If set to `null`, then the Nginx default is respected. Default: `null`. + `ca_certificates`
*optional* | Array of `CA Certificate` object UUIDs that are used to build the trust store while verifying upstream server's TLS certificate. If set to `null` when Nginx default is respected. If default CA list in Nginx are not specified and TLS verification is enabled, then handshake with upstream server will always fail (because no CA are trusted). With form-encoded, the notation is `ca_certificates[]=4e3ad2e4-0bc4-4638-8e34-c84a417ba39b&ca_certificates[]=51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515`. With JSON, use an Array. + `url`
*shorthand-attribute* | Shorthand attribute to set `protocol`, `host`, `port` and `path` at once. This attribute is write-only (the Admin API never returns the URL). + +service_json: | + { + "id": "9748f662-7711-4a90-8186-dc02f10eb0f5", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"4e3ad2e4-0bc4-4638-8e34-c84a417ba39b"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + } + +service_data: | + "data": [{ + "id": "a5fb8d9b-a99d-40e9-9d35-72d42a62d83a", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + }, { + "id": "fc73f2af-890d-4f9b-8363-af8945001f7f", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/another_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["admin", "high-priority", "critical"], + "client_certificate": {"id":"4506673d-c825-444c-a25b-602e3c2ec16e"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + }], + +route_body: | + Attributes | Description + ---:| --- + `name`
*optional* | The name of the Route. + `protocols` | A list of the protocols this Route should allow. When set to `["https"]`, HTTP requests are answered with a request to upgrade to HTTPS. Default: `["http", "https"]`. + `methods`
*semi-optional* | A list of HTTP methods that match this Route. + `hosts`
*semi-optional* | A list of domain names that match this Route. With form-encoded, the notation is `hosts[]=example.com&hosts[]=foo.test`. With JSON, use an Array. + `paths`
*semi-optional* | A list of paths that match this Route. With form-encoded, the notation is `paths[]=/foo&paths[]=/bar`. With JSON, use an Array. + `headers`
*semi-optional* | One or more lists of values indexed by header name that will cause this Route to match if present in the request. The `Host` header cannot be used with this attribute: hosts should be specified using the `hosts` attribute. + `https_redirect_status_code` | The status code Kong responds with when all properties of a Route match except the protocol i.e. if the protocol of the request is `HTTP` instead of `HTTPS`. `Location` header is injected by Kong if the field is set to 301, 302, 307 or 308. Accepted values are: `426`, `301`, `302`, `307`, `308`. Default: `426`. + `regex_priority`
*optional* | A number used to choose which route resolves a given request when several routes match it using regexes simultaneously. When two routes match the path and have the same `regex_priority`, the older one (lowest `created_at`) is used. Note that the priority for non-regex routes is different (longer non-regex routes are matched before shorter ones). Default: `0`. + `strip_path`
*optional* | When matching a Route via one of the `paths`, strip the matching prefix from the upstream request URL. Default: `true`. + `path_handling`
*optional* | Controls how the Service path, Route path and requested path are combined when sending a request to the upstream. See above for a detailed description of each behavior. Accepted values are: `"v0"`, `"v1"`. Default: `"v0"`. + `preserve_host`
*optional* | When matching a Route via one of the `hosts` domain names, use the request `Host` header in the upstream request headers. If set to `false`, the upstream `Host` header will be that of the Service's `host`. + `request_buffering` | Whether to enable request body buffering or not. With HTTP 1.1, it may make sense to turn this off on services that receive data with chunked transfer encoding. Default: `true`. + `response_buffering` | Whether to enable response body buffering or not. With HTTP 1.1, it may make sense to turn this off on services that send data with chunked transfer encoding. Default: `true`. + `snis`
*semi-optional* | A list of SNIs that match this Route when using stream routing. + `sources`
*semi-optional* | A list of IP sources of incoming connections that match this Route when using stream routing. Each entry is an object with fields "ip" (optionally in CIDR range notation) and/or "port". + `destinations`
*semi-optional* | A list of IP destinations of incoming connections that match this Route when using stream routing. Each entry is an object with fields "ip" (optionally in CIDR range notation) and/or "port". + `tags`
*optional* | An optional set of strings associated with the Route for grouping and filtering. + `service`
*optional* | The Service this Route is associated to. This is where the Route proxies traffic to. With form-encoded, the notation is `service.id=` or `service.name=`. With JSON, use "`"service":{"id":""}` or `"service":{"name":""}`. + +route_json: | + { + "id": "d35165e2-d03e-461a-bdeb-dad0a112abfe", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["http", "https"], + "methods": ["GET", "POST"], + "hosts": ["example.com", "foo.test"], + "paths": ["/foo", "/bar"], + "headers": {"x-another-header":["bla"], "x-my-header":["foo", "bar"]}, + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "tags": ["user-level", "low-priority"], + "service": {"id":"af8330d3-dbdc-48bd-b1be-55b98608834b"} + } + +route_data: | + "data": [{ + "id": "a9daa3ba-8186-4a0d-96e8-00d80ce7240b", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["http", "https"], + "methods": ["GET", "POST"], + "hosts": ["example.com", "foo.test"], + "paths": ["/foo", "/bar"], + "headers": {"x-another-header":["bla"], "x-my-header":["foo", "bar"]}, + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "tags": ["user-level", "low-priority"], + "service": {"id":"127dfc88-ed57-45bf-b77a-a9d3a152ad31"} + }, { + "id": "9aa116fd-ef4a-4efa-89bf-a0b17c4be982", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-route", + "protocols": ["tcp", "tls"], + "https_redirect_status_code": 426, + "regex_priority": 0, + "strip_path": true, + "path_handling": "v0", + "preserve_host": false, + "request_buffering": true, + "response_buffering": true, + "snis": ["foo.test", "example.com"], + "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "destinations": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "tags": ["admin", "high-priority", "critical"], + "service": {"id":"ba641b07-e74a-430a-ab46-94b61e5ea66b"} + }], + +consumer_body: | + Attributes | Description + ---:| --- + `username`
*semi-optional* | The unique username of the Consumer. You must send either this field or `custom_id` with the request. + `custom_id`
*semi-optional* | Field for storing an existing unique ID for the Consumer - useful for mapping Kong with users in your existing database. You must send either this field or `username` with the request. + `tags`
*optional* | An optional set of strings associated with the Consumer for grouping and filtering. + +consumer_json: | + { + "id": "ec1a1f6f-2aa4-4e58-93ff-b56368f19b27", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "tags": ["user-level", "low-priority"] + } + +consumer_data: | + "data": [{ + "id": "a4407883-c166-43fd-80ca-3ca035b0cdb7", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "tags": ["user-level", "low-priority"] + }, { + "id": "01c23299-839c-49a5-a6d5-8864c09184af", + "created_at": 1422386534, + "username": "my-username", + "custom_id": "my-custom-id", + "tags": ["admin", "high-priority", "critical"] + }], + +plugin_body: | + Attributes | Description + ---:| --- + `name` | The name of the Plugin that's going to be added. Currently, the Plugin must be installed in every Kong instance separately. + `route`
*optional* | If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the Route being used. Default: `null`.With form-encoded, the notation is `route.id=` or `route.name=`. With JSON, use "`"route":{"id":""}` or `"route":{"name":""}`. + `service`
*optional* | If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched. Default: `null`.With form-encoded, the notation is `service.id=` or `service.name=`. With JSON, use "`"service":{"id":""}` or `"service":{"name":""}`. + `consumer`
*optional* | If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer. Default: `null`.With form-encoded, the notation is `consumer.id=` or `consumer.username=`. With JSON, use "`"consumer":{"id":""}` or `"consumer":{"username":""}`. + `config`
*optional* | The configuration properties for the Plugin which can be found on the plugins documentation page in the [Kong Hub](https://docs.konghq.com/hub/). + `protocols` | A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support `"tcp"` and `"tls"`. Default: `["grpc", "grpcs", "http",`` "https"]`. + `enabled`
*optional* | Whether the plugin is applied. Default: `true`. + `tags`
*optional* | An optional set of strings associated with the Plugin for grouping and filtering. + +plugin_json: | + { + "id": "ce44eef5-41ed-47f6-baab-f725cecf98c7", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"minute":20, "hour":500}, + "protocols": ["http", "https"], + "enabled": true, + "tags": ["user-level", "low-priority"] + } + +plugin_data: | + "data": [{ + "id": "02621eee-8309-4bf6-b36b-a82017a5393e", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"minute":20, "hour":500}, + "protocols": ["http", "https"], + "enabled": true, + "tags": ["user-level", "low-priority"] + }, { + "id": "66c7b5c4-4aaf-4119-af1e-ee3ad75d0af4", + "name": "rate-limiting", + "created_at": 1422386534, + "route": null, + "service": null, + "consumer": null, + "config": {"minute":20, "hour":500}, + "protocols": ["tcp", "tls"], + "enabled": true, + "tags": ["admin", "high-priority", "critical"] + }], + +certificate_body: | + Attributes | Description + ---:| --- + `cert` | PEM-encoded public certificate chain of the SSL key pair. + `key` | PEM-encoded private key of the SSL key pair. + `tags`
*optional* | An optional set of strings associated with the Certificate for grouping and filtering. + `snis`
*shorthand-attribute* | An array of zero or more hostnames to associate with this certificate as SNIs. This is a sugar parameter that will, under the hood, create an SNI object and associate it with this certificate for your convenience. To set this attribute this certificate must have a valid private key associated with it. + +certificate_json: | + { + "id": "7fca84d6-7d37-4a74-a7b0-93e576089a41", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "tags": ["user-level", "low-priority"] + } + +certificate_data: | + "data": [{ + "id": "d044b7d4-3dc2-4bbc-8e9f-6b7a69416df6", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "tags": ["user-level", "low-priority"] + }, { + "id": "a9b2107f-a214-47b3-add4-46b942187924", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "tags": ["admin", "high-priority", "critical"] + }], + +ca_certificate_body: | + Attributes | Description + ---:| --- + `cert` | PEM-encoded public certificate of the CA. + `cert_digest`
*optional* | SHA256 hex digest of the public certificate. + `tags`
*optional* | An optional set of strings associated with the Certificate for grouping and filtering. + +ca_certificate_json: | + { + "id": "04fbeacf-a9f1-4a5d-ae4a-b0407445db3f", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["user-level", "low-priority"] + } + +ca_certificate_data: | + "data": [{ + "id": "43429efd-b3a5-4048-94cb-5cc4029909bb", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["user-level", "low-priority"] + }, { + "id": "d26761d5-83a4-4f24-ac6c-cff276f2b79c", + "created_at": 1422386534, + "cert": "-----BEGIN CERTIFICATE-----...", + "cert_digest": "c641e28d77e93544f2fa87b2cf3f3d51...", + "tags": ["admin", "high-priority", "critical"] + }], + +sni_body: | + Attributes | Description + ---:| --- + `name` | The SNI name to associate with the given certificate. + `tags`
*optional* | An optional set of strings associated with the SNIs for grouping and filtering. + `certificate` | The id (a UUID) of the certificate with which to associate the SNI hostname. The Certificate must have a valid private key associated with it to be used by the SNI object. With form-encoded, the notation is `certificate.id=`. With JSON, use "`"certificate":{"id":""}`. + +sni_json: | + { + "id": "91020192-062d-416f-a275-9addeeaffaf2", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["user-level", "low-priority"], + "certificate": {"id":"a2e013e8-7623-4494-a347-6d29108ff68b"} + } + +sni_data: | + "data": [{ + "id": "147f5ef0-1ed6-4711-b77f-489262f8bff7", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["user-level", "low-priority"], + "certificate": {"id":"a3ad71a8-6685-4b03-a101-980a953544f6"} + }, { + "id": "b87eb55d-69a1-41d2-8653-8d706eecefc0", + "name": "my-sni", + "created_at": 1422386534, + "tags": ["admin", "high-priority", "critical"], + "certificate": {"id":"4e8d95d4-40f2-4818-adcb-30e00c349618"} + }], + +upstream_body: | + Attributes | Description + ---:| --- + `name` | This is a hostname, which must be equal to the `host` of a Service. + `algorithm`
*optional* | Which load balancing algorithm to use. Accepted values are: `"consistent-hashing"`, `"least-connections"`, `"round-robin"`. Default: `"round-robin"`. + `hash_on`
*optional* | What to use as hashing input. Using `none` results in a weighted-round-robin scheme with no hashing. Accepted values are: `"none"`, `"consumer"`, `"ip"`, `"header"`, `"cookie"`. Default: `"none"`. + `hash_fallback`
*optional* | What to use as hashing input if the primary `hash_on` does not return a hash (eg. header is missing, or no Consumer identified). Not available if `hash_on` is set to `cookie`. Accepted values are: `"none"`, `"consumer"`, `"ip"`, `"header"`, `"cookie"`. Default: `"none"`. + `hash_on_header`
*semi-optional* | The header name to take the value from as hash input. Only required when `hash_on` is set to `header`. + `hash_fallback_header`
*semi-optional* | The header name to take the value from as hash input. Only required when `hash_fallback` is set to `header`. + `hash_on_cookie`
*semi-optional* | The cookie name to take the value from as hash input. Only required when `hash_on` or `hash_fallback` is set to `cookie`. If the specified cookie is not in the request, Kong will generate a value and set the cookie in the response. + `hash_on_cookie_path`
*semi-optional* | The cookie path to set in the response headers. Only required when `hash_on` or `hash_fallback` is set to `cookie`. Default: `"/"`. + `slots`
*optional* | The number of slots in the loadbalancer algorithm (`10`-`65536`). Default: `10000`. + `healthchecks.active.``https_verify_certificate`
*optional* | Whether to check the validity of the SSL certificate of the remote host when performing active health checks using HTTPS. Default: `true`. + `healthchecks.active.``unhealthy.http_statuses`
*optional* | An array of HTTP statuses to consider a failure, indicating unhealthiness, when returned by a probe in active health checks. Default: `[429, 404, 500, 501, 502, 503,`` 504, 505]`. With form-encoded, the notation is `http_statuses[]=429&http_statuses[]=404`. With JSON, use an Array. + `healthchecks.active.``unhealthy.tcp_failures`
*optional* | Number of TCP failures in active probes to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.timeouts`
*optional* | Number of timeouts in active probes to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.http_failures`
*optional* | Number of HTTP failures in active probes (as defined by `healthchecks.active.unhealthy.http_statuses`) to consider a target unhealthy. Default: `0`. + `healthchecks.active.``unhealthy.interval`
*optional* | Interval between active health checks for unhealthy targets (in seconds). A value of zero indicates that active probes for unhealthy targets should not be performed. Default: `0`. + `healthchecks.active.``http_path`
*optional* | Path to use in GET HTTP request to run as a probe on active health checks. Default: `"/"`. + `healthchecks.active.``timeout`
*optional* | Socket timeout for active health checks (in seconds). Default: `1`. + `healthchecks.active.``healthy.http_statuses`
*optional* | An array of HTTP statuses to consider a success, indicating healthiness, when returned by a probe in active health checks. Default: `[200, 302]`. With form-encoded, the notation is `http_statuses[]=200&http_statuses[]=302`. With JSON, use an Array. + `healthchecks.active.``healthy.interval`
*optional* | Interval between active health checks for healthy targets (in seconds). A value of zero indicates that active probes for healthy targets should not be performed. Default: `0`. + `healthchecks.active.``healthy.successes`
*optional* | Number of successes in active probes (as defined by `healthchecks.active.healthy.http_statuses`) to consider a target healthy. Default: `0`. + `healthchecks.active.``https_sni`
*optional* | The hostname to use as an SNI (Server Name Identification) when performing active health checks using HTTPS. This is particularly useful when Targets are configured using IPs, so that the target host's certificate can be verified with the proper SNI. + `healthchecks.active.``concurrency`
*optional* | Number of targets to check concurrently in active health checks. Default: `10`. + `healthchecks.active.type`
*optional* | Whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection. Accepted values are: `"tcp"`, `"http"`, `"https"`, `"grpc"`, `"grpcs"`. Default: `"http"`. + `healthchecks.passive.``unhealthy.http_failures`
*optional* | Number of HTTP failures in proxied traffic (as defined by `healthchecks.passive.unhealthy.http_statuses`) to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``unhealthy.http_statuses`
*optional* | An array of HTTP statuses which represent unhealthiness when produced by proxied traffic, as observed by passive health checks. Default: `[429, 500, 503]`. With form-encoded, the notation is `http_statuses[]=429&http_statuses[]=500`. With JSON, use an Array. + `healthchecks.passive.``unhealthy.tcp_failures`
*optional* | Number of TCP failures in proxied traffic to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``unhealthy.timeouts`
*optional* | Number of timeouts in proxied traffic to consider a target unhealthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``type`
*optional* | Whether to perform passive health checks interpreting HTTP/HTTPS statuses, or just check for TCP connection success. In passive checks, `http` and `https` options are equivalent. Accepted values are: `"tcp"`, `"http"`, `"https"`, `"grpc"`, `"grpcs"`. Default: `"http"`. + `healthchecks.passive.``healthy.successes`
*optional* | Number of successes in proxied traffic (as defined by `healthchecks.passive.healthy.http_statuses`) to consider a target healthy, as observed by passive health checks. Default: `0`. + `healthchecks.passive.``healthy.http_statuses`
*optional* | An array of HTTP statuses which represent healthiness when produced by proxied traffic, as observed by passive health checks. Default: `[200, 201, 202, 203, 204, 205,`` 206, 207, 208, 226, 300, 301,`` 302, 303, 304, 305, 306, 307,`` 308]`. With form-encoded, the notation is `http_statuses[]=200&http_statuses[]=201`. With JSON, use an Array. + `healthchecks.threshold`
*optional* | The minimum percentage of the upstream's targets' weight that must be available for the whole upstream to be considered healthy. Default: `0`. + `tags`
*optional* | An optional set of strings associated with the Upstream for grouping and filtering. + `host_header`
*optional* | The hostname to be used as `Host` header when proxying requests through Kong. + `client_certificate`
*optional* | If set, the certificate to be used as client certificate while TLS handshaking to the upstream server.With form-encoded, the notation is `client_certificate.id=`. With JSON, use "`"client_certificate":{"id":""}`. + +upstream_json: | + { + "id": "58c8ccbb-eafb-4566-991f-2ed4f678fa70", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "https_verify_certificate": true, + "unhealthy": { + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "tcp_failures": 0, + "timeouts": 0, + "http_failures": 0, + "interval": 0 + }, + "http_path": "/", + "timeout": 1, + "healthy": { + "http_statuses": [200, 302], + "interval": 0, + "successes": 0 + }, + "https_sni": "example.com", + "concurrency": 10, + "type": "http" + }, + "passive": { + "unhealthy": { + "http_failures": 0, + "http_statuses": [429, 500, 503], + "tcp_failures": 0, + "timeouts": 0 + }, + "type": "http", + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + } + }, + "threshold": 0 + }, + "tags": ["user-level", "low-priority"], + "host_header": "example.com", + "client_certificate": {"id":"ea29aaa3-3b2d-488c-b90c-56df8e0dd8c6"} + } + +upstream_data: | + "data": [{ + "id": "4fe14415-73d5-4f00-9fbc-c72a0fccfcb2", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "https_verify_certificate": true, + "unhealthy": { + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "tcp_failures": 0, + "timeouts": 0, + "http_failures": 0, + "interval": 0 + }, + "http_path": "/", + "timeout": 1, + "healthy": { + "http_statuses": [200, 302], + "interval": 0, + "successes": 0 + }, + "https_sni": "example.com", + "concurrency": 10, + "type": "http" + }, + "passive": { + "unhealthy": { + "http_failures": 0, + "http_statuses": [429, 500, 503], + "tcp_failures": 0, + "timeouts": 0 + }, + "type": "http", + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + } + }, + "threshold": 0 + }, + "tags": ["user-level", "low-priority"], + "host_header": "example.com", + "client_certificate": {"id":"a3395f66-2af6-4c79-bea2-1b6933764f80"} + }, { + "id": "885a0392-ef1b-4de3-aacf-af3f1697ce2c", + "created_at": 1422386534, + "name": "my-upstream", + "algorithm": "round-robin", + "hash_on": "none", + "hash_fallback": "none", + "hash_on_cookie_path": "/", + "slots": 10000, + "healthchecks": { + "active": { + "https_verify_certificate": true, + "unhealthy": { + "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505], + "tcp_failures": 0, + "timeouts": 0, + "http_failures": 0, + "interval": 0 + }, + "http_path": "/", + "timeout": 1, + "healthy": { + "http_statuses": [200, 302], + "interval": 0, + "successes": 0 + }, + "https_sni": "example.com", + "concurrency": 10, + "type": "http" + }, + "passive": { + "unhealthy": { + "http_failures": 0, + "http_statuses": [429, 500, 503], + "tcp_failures": 0, + "timeouts": 0 + }, + "type": "http", + "healthy": { + "successes": 0, + "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] + } + }, + "threshold": 0 + }, + "tags": ["admin", "high-priority", "critical"], + "host_header": "example.com", + "client_certificate": {"id":"f5a9c0ca-bdbb-490f-8928-2ca95836239a"} + }], + +target_body: | + Attributes | Description + ---:| --- + `target` | The target address (ip or hostname) and port. If the hostname resolves to an SRV record, the `port` value will be overridden by the value from the DNS record. + `weight`
*optional* | The weight this target gets within the upstream loadbalancer (`0`-`65535`). If the hostname resolves to an SRV record, the `weight` value will be overridden by the value from the DNS record. Default: `100`. + `tags`
*optional* | An optional set of strings associated with the Target for grouping and filtering. + +target_json: | + { + "id": "173a6cee-90d1-40a7-89cf-0329eca780a6", + "created_at": 1422386534, + "upstream": {"id":"bdab0e47-4e37-4f0b-8fd0-87d95cc4addc"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["user-level", "low-priority"] + } + +target_data: | + "data": [{ + "id": "f00c6da4-3679-4b44-b9fb-36a19bd3ae83", + "created_at": 1422386534, + "upstream": {"id":"0c61e164-6171-4837-8836-8f5298726d53"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["user-level", "low-priority"] + }, { + "id": "5027BBC1-508C-41F8-87F2-AB1801E9D5C3", + "created_at": 1422386534, + "upstream": {"id":"68FDB05B-7B08-47E9-9727-AF7F897CFF1A"}, + "target": "example.com:8000", + "weight": 100, + "tags": ["admin", "high-priority", "critical"] + }], + + +--- + + + +Kong comes with an **internal** RESTful Admin API for administration purposes. +In [DB-less mode][db-less], this Admin API can be used to load a new declarative +configuration, and for inspecting the current configuration. In DB-less mode, +the Admin API for each Kong node functions independently, reflecting the memory state +of that particular Kong node. This is the case because there is no database +coordination between Kong nodes. + +- `8001` is the default port on which the Admin API listens. +- `8444` is the default port for HTTPS traffic to the Admin API. + +This API provides full control over Kong, so care should be taken when setting +up Kong environments to avoid undue public exposure of this API. +See [this document][secure-admin-api] for a discussion +of methods to secure the Admin API. + +## Supported Content Types + +The Admin API accepts 3 content types on every endpoint: + +- **application/json** + +Handy for complex bodies (ex: complex plugin configuration), in that case simply send +a JSON representation of the data you want to send. Example: + +```json +{ + "config": { + "limit": 10, + "period": "seconds" + } +} +``` + + +- **application/x-www-form-urlencoded** + +Simple enough for basic request bodies, you will probably use it most of the time. +Note that when sending nested values, Kong expects nested objects to be referenced +with dotted keys. Example: + +``` +config.limit=10&config.period=seconds +``` + + +- **multipart/form-data** + +Similar to URL-encoded, this content type uses dotted keys to reference nested objects. +Here is an example of sending a Lua file to the pre-function Kong plugin: + +``` +curl -i -X POST http://localhost:8001/services/plugin-testing/plugins \ + -F "name=pre-function" \ + -F "config.functions=@custom-auth.lua" +``` + +--- + +## Information Routes + + + +### Retrieve Node Information + +Retrieve generic details about a node. + +
/
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "hostname": "", + "node_id": "6a72192c-a3a1-4c8d-95c6-efabae9fb969", + "lua_version": "LuaJIT 2.1.0-beta3", + "plugins": { + "available_on_server": [ + ... + ], + "enabled_in_cluster": [ + ... + ] + }, + "configuration" : { + ... + }, + "tagline": "Welcome to Kong", + "version": "0.14.0" +} +``` + +* `node_id`: A UUID representing the running Kong node. This UUID + is randomly generated when Kong starts, so the node will have a + different `node_id` each time it is restarted. +* `available_on_server`: Names of plugins that are installed on the node. +* `enabled_in_cluster`: Names of plugins that are enabled/configured. + That is, the plugins configurations currently in the datastore shared + by all Kong nodes. + + +--- + +### List Available Endpoints + +List all available endpoints provided by the Admin API. + +
/endpoints
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "data": [ + "/", + "/acls", + "/acls/{acls}", + "/acls/{acls}/consumer", + "/basic-auths", + "/basic-auths/{basicauth_credentials}", + "/basic-auths/{basicauth_credentials}/consumer", + "/ca_certificates", + "/ca_certificates/{ca_certificates}", + "/cache", + "/cache/{key}", + "..." + ] +} +``` + + +--- + +### Validate A Configuration against A Schema + +Check validity of a configuration against its entity schema. +This allows you to test your input before submitting a request +to the entity endpoints of the Admin API. + +Note that this only performs the schema validation checks, +checking that the input configuration is well-formed. +A requests to the entity endpoint using the given configuration +may still fail due to other reasons, such as invalid foreign +key relationships or uniqueness check failures against the +contents of the data store. + + +
/schemas/{entity}/validate
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "message": "schema validation successful" +} +``` + + +--- + +### Retrieve Entity Schema + +Retrieve the schema of an entity. This is useful to +understand what fields an entity accepts, and can be used for building +third-party integrations to the Kong. + + +
/schemas/{entity name}
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "fields": [ + { + "id": { + "auto": true, + "type": "string", + "uuid": true + } + }, + { + "created_at": { + "auto": true, + "timestamp": true, + "type": "integer" + } + }, + ... + ] +} +``` + + +--- + +### Retrieve Plugin Schema + +Retrieve the schema of a plugin's configuration. This is useful to +understand what fields a plugin accepts, and can be used for building +third-party integrations to the Kong's plugin system. + + +
/schemas/plugins/{plugin name}
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "fields": { + "hide_credentials": { + "default": false, + "type": "boolean" + }, + "key_names": { + "default": "function", + "required": true, + "type": "array" + } + } +} +``` + + +--- + +## Health Routes + + + +### Retrieve Node Status + +Retrieve usage information about a node, with some basic information +about the connections being processed by the underlying nginx process, +the status of the database connection, and node's memory usage. + +If you want to monitor the Kong process, since Kong is built on top +of nginx, every existing nginx monitoring tool or agent can be used. + + +
/status
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "database": { + "reachable": true + }, + "memory": { + "workers_lua_vms": [{ + "http_allocated_gc": "0.02 MiB", + "pid": 18477 + }, { + "http_allocated_gc": "0.02 MiB", + "pid": 18478 + }], + "lua_shared_dicts": { + "kong": { + "allocated_slabs": "0.04 MiB", + "capacity": "5.00 MiB" + }, + "kong_db_cache": { + "allocated_slabs": "0.80 MiB", + "capacity": "128.00 MiB" + }, + } + }, + "server": { + "total_requests": 3, + "connections_active": 1, + "connections_accepted": 1, + "connections_handled": 1, + "connections_reading": 0, + "connections_writing": 1, + "connections_waiting": 0 + } +} +``` + +* `memory`: Metrics about the memory usage. + * `workers_lua_vms`: An array with all workers of the Kong node, where each + entry contains: + * `http_allocated_gc`: HTTP submodule's Lua virtual machine's memory + usage information, as reported by `collectgarbage("count")`, for every + active worker, i.e. a worker that received a proxy call in the last 10 + seconds. + * `pid`: worker's process identification number. + * `lua_shared_dicts`: An array of information about dictionaries that are + shared with all workers in a Kong node, where each array node contains how + much memory is dedicated for the specific shared dictionary (`capacity`) + and how much of said memory is in use (`allocated_slabs`). + These shared dictionaries have least recent used (LRU) eviction + capabilities, so a full dictionary, where `allocated_slabs == capacity`, + will work properly. However for some dictionaries, e.g. cache HIT/MISS + shared dictionaries, increasing their size can be beneficial for the + overall performance of a Kong node. + * The memory usage unit and precision can be changed using the querystring + arguments `unit` and `scale`: + * `unit`: one of `b/B`, `k/K`, `m/M`, `g/G`, which will return results + in bytes, kibibytes, mebibytes, or gibibytes, respectively. When + "bytes" are requested, the memory values in the response will have a + number type instead of string. Defaults to `m`. + * `scale`: the number of digits to the right of the decimal points when + values are given in human-readable memory strings (unit other than + "bytes"). Defaults to `2`. + You can get the shared dictionaries memory usage in kibibytes with 4 + digits of precision by doing: `GET /status?unit=k&scale=4` +* `server`: Metrics about the nginx HTTP/S server. + * `total_requests`: The total number of client requests. + * `connections_active`: The current number of active client + connections including Waiting connections. + * `connections_accepted`: The total number of accepted client + connections. + * `connections_handled`: The total number of handled connections. + Generally, the parameter value is the same as accepts unless + some resource limits have been reached. + * `connections_reading`: The current number of connections + where Kong is reading the request header. + * `connections_writing`: The current number of connections + where nginx is writing the response back to the client. + * `connections_waiting`: The current number of idle client + connections waiting for a request. +* `database`: Metrics about the database. + * `reachable`: A boolean value reflecting the state of the + database connection. Please note that this flag **does not** + reflect the health of the database itself. + + +--- + +## Declarative Configuration + +Loading the declarative configuration of entities into Kong +can be done in two ways: at start-up, through the `declarative_config` +property, or at run-time, through the Admin API using the `/config` +endpoint. + +To get started using declarative configuration, you need a file +(in YAML or JSON format) containing entity definitions. You can +generate a sample declarative configuration with the command: + +``` +kong config init +``` + +It generates a file named `kong.yml` in the current directory, +containing the appropriate structure and examples. + + +### Reload Declarative Configuration + +This endpoint allows resetting a DB-less Kong with a new +declarative configuration data file. All previous contents +are erased from memory, and the entities specified in the +given file take their place. + +To learn more about the file format, please read the +[declarative configuration][db-less] documentation. + + +
/config
+ +{:.indent} +Attributes | Description +---:| --- +`config`
**required** | The config data (in YAML or JSON format) to be loaded. + + +#### Request Querystring Parameters + +Attributes | Description +---:| --- +`check_hash`
*optional* | If set to 1, Kong will compare the hash of the input config data against that of the previous one. If the configuration is identical, it will not reload it and will return HTTP 304. + + +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { "services": [], + "routes": [] + } +} +``` + +The response contains a list of all the entities that were parsed from the +input file. + + +--- + +## Tags + +Tags are strings associated to entities in Kong. Each tag must be composed of one or more +alphanumeric characters, `_`, `-`, `.` or `~`. + +Most core entities can be *tagged* via their `tags` attribute, upon creation or edition. + +Tags can be used to filter core entities as well, via the `?tags` querystring parameter. + +For example: if you normally get a list of all the Services by doing: + +``` +GET /services +``` + +You can get the list of all the Services tagged `example` by doing: + +``` +GET /services?tags=example +``` + +Similarly, if you want to filter Services so that you only get the ones tagged `example` *and* +`admin`, you can do that like so: + +``` +GET /services?tags=example,admin +``` + +Finally, if you wanted to filter the Services tagged `example` *or* `admin`, you could use: + +``` +GET /services?tags=example/admin +``` + +Some notes: + +* A maximum of 5 tags can be queried simultaneously in a single request with `,` or `/` +* Mixing operators is not supported: if you try to mix `,` with `/` in the same querystring, + you will receive an error. +* You may need to quote and/or escape some characters when using them from the + command line. +* Filtering by `tags` is not supported in foreign key relationship endpoints. For example, + the `tags` parameter will be ignored in a request such as `GET /services/foo/routes?tags=a,b` +* `offset` parameters are not guaranteed to work if the `tags` parameter is altered or removed + + +### List All Tags + +Returns a paginated list of all the tags in the system. + +The list of entities will not be restricted to a single entity type: all the +entities tagged with tags will be present on this list. + +If an entity is tagged with more than one tag, the `entity_id` for that entity +will appear more than once in the resulting list. Similarly, if several entities +have been tagged with the same tag, the tag will appear in several items of this list. + + +
/tags
+ +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "data": [ + { "entity_name": "services", + "entity_id": "acf60b10-125c-4c1a-bffe-6ed55daefba4", + "tag": "s1", + }, + { "entity_name": "services", + "entity_id": "acf60b10-125c-4c1a-bffe-6ed55daefba4", + "tag": "s2", + }, + { "entity_name": "routes", + "entity_id": "60631e85-ba6d-4c59-bd28-e36dd90f6000", + "tag": "s1", + }, + ... + ], + "offset": "c47139f3-d780-483d-8a97-17e9adc5a7ab", + "next": "/tags?offset=c47139f3-d780-483d-8a97-17e9adc5a7ab", + } +} +``` + + +--- + +### List Entity Ids by Tag + +Returns the entities that have been tagged with the specified tag. + +The list of entities will not be restricted to a single entity type: all the +entities tagged with tags will be present on this list. + + +
/tags/{tags}
+ +#### Response + +``` +HTTP 200 OK +``` + +``` json +{ + { + "data": [ + { "entity_name": "services", + "entity_id": "c87440e1-0496-420b-b06f-dac59544bb6c", + "tag": "example", + }, + { "entity_name": "routes", + "entity_id": "8a99e4b1-d268-446b-ab8b-cd25cff129b1", + "tag": "example", + }, + ... + ], + "offset": "1fb491c4-f4a7-4bca-aeba-7f3bcee4d2f9", + "next": "/tags/example?offset=1fb491c4-f4a7-4bca-aeba-7f3bcee4d2f9", + } +} +``` + + +--- + +## Service Object + +Service entities, as the name implies, are abstractions of each of your own +upstream services. Examples of Services would be a data transformation +microservice, a billing API, etc. + +The main attribute of a Service is its URL (where Kong should proxy traffic +to), which can be set as a single string or by specifying its `protocol`, +`host`, `port` and `path` individually. + +Services are associated to Routes (a Service can have many Routes associated +with it). Routes are entry-points in Kong and define rules to match client +requests. Once a Route is matched, Kong proxies the request to its associated +Service. See the [Proxy Reference][proxy-reference] for a detailed explanation +of how Kong proxies traffic. + +Services can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.service_json }} +``` + +### List Services + +##### List All Services + +
/services
+ + +##### List Services Associated to a Specific Certificate + +
/certificates/{certificate name or id}/services
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate whose Services are to be retrieved. When using this endpoint, only Services associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.service_data }} + "next": "http://localhost:8001/services?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Service + +##### Retrieve Service + +
/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. + + +##### Retrieve Service Associated to a Specific Certificate + +
/certificates/{certificate id}/services/{service name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. + + +##### Retrieve Service Associated to a Specific Route + +
/routes/{route name or id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route associated to the Service to be retrieved. + + +##### Retrieve Service Associated to a Specific Plugin + +
/plugins/{plugin id}/service
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Service to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.service_json }} +``` + + +--- + +## Route Object + +Route entities define rules to match client requests. Each Route is +associated with a Service, and a Service may have multiple Routes associated to +it. Every request matching a given Route will be proxied to its associated +Service. + +The combination of Routes and Services (and the separation of concerns between +them) offers a powerful routing mechanism with which it is possible to define +fine-grained entry-points in Kong leading to different upstream services of +your infrastructure. + +You need at least one matching rule that applies to the protocol being matched +by the Route. Depending on the protocols configured to be matched by the Route +(as defined with the `protocols` field), this means that at least one of the +following attributes must be set: + +* For `http`, at least one of `methods`, `hosts`, `headers` or `paths`; +* For `https`, at least one of `methods`, `hosts`, `headers`, `paths` or `snis`; +* For `tcp`, at least one of `sources` or `destinations`; +* For `tls`, at least one of `sources`, `destinations` or `snis`; +* For `grpc`, at least one of `hosts`, `headers` or `paths`; +* For `grpcs`, at least one of `hosts`, `headers`, `paths` or `snis`. + +#### Path handling algorithms + +`"v0"` is the behavior used in Kong 0.x and 2.x. It treats `service.path`, `route.path` and request path as +*segments* of a URL. It will always join them via slashes. Given a service path `/s`, route path `/r` +and request path `/re`, the concatenated path will be `/s/re`. If the resulting path is a single slash, +no further transformation is done to it. If it's longer, then the trailing slash is removed. + +`"v1"` is the behavior used in Kong 1.x. It treats `service.path` as a *prefix*, and ignores the initial +slashes of the request and route paths. Given service path `/s`, route path `/r` and request path `/re`, +the concatenated path will be `/sre`. + +Both versions of the algorithm detect "double slashes" when combining paths, replacing them by single +slashes. + +In the following table, `s` is the Service and `r` is the Route. + +| `s.path` | `r.path` | `r.strip_path` | `r.path_handling` | request path | proxied path | +|----------|----------|----------------|-------------------|--------------|---------------| +| `/s` | `/fv0` | `false` | `v0` | `/fv0req` | `/s/fv0req` | +| `/s` | `/fv1` | `false` | `v1` | `/fv1req` | `/sfv1req` | +| `/s` | `/tv0` | `true` | `v0` | `/tv0req` | `/s/req` | +| `/s` | `/tv1` | `true` | `v1` | `/tv1req` | `/sreq` | +| `/s` | `/fv0/` | `false` | `v0` | `/fv0/req` | `/s/fv0/req` | +| `/s` | `/fv1/` | `false` | `v1` | `/fv1/req` | `/sfv1/req` | +| `/s` | `/tv0/` | `true` | `v0` | `/tv0/req` | `/s/req` | +| `/s` | `/tv1/` | `true` | `v1` | `/tv1/req` | `/sreq` | + + +Routes can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.route_json }} +``` + +### List Routes + +##### List All Routes + +
/routes
+ + +##### List Routes Associated to a Specific Service + +
/services/{service name or id}/routes
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier or the `name` attribute of the Service whose Routes are to be retrieved. When using this endpoint, only Routes associated to the specified Service will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.route_data }} + "next": "http://localhost:8001/routes?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Route + +##### Retrieve Route + +
/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to retrieve. + + +##### Retrieve Route Associated to a Specific Service + +
/services/{service name or id}/routes/{route name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. +`route name or id`
**required** | The unique identifier **or** the name of the Route to retrieve. + + +##### Retrieve Route Associated to a Specific Plugin + +
/plugins/{plugin id}/route
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Route to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.route_json }} +``` + + +--- + +## Consumer Object + +The Consumer object represents a consumer - or a user - of a Service. You can +either rely on Kong as the primary datastore, or you can map the consumer list +with your database to keep consistency between Kong and your existing primary +datastore. + +Consumers can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.consumer_json }} +``` + +### List Consumers + +##### List All Consumers + +
/consumers
+ + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.consumer_data }} + "next": "http://localhost:8001/consumers?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Consumer + +##### Retrieve Consumer + +
/consumers/{consumer username or id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to retrieve. + + +##### Retrieve Consumer Associated to a Specific Plugin + +
/plugins/{plugin id}/consumer
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin associated to the Consumer to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.consumer_json }} +``` + + +--- + +## Plugin Object + +A Plugin entity represents a plugin configuration that will be executed during +the HTTP request/response lifecycle. It is how you can add functionalities +to Services that run behind Kong, like Authentication or Rate Limiting for +example. You can find more information about how to install and what values +each plugin takes by visiting the [Kong Hub](https://docs.konghq.com/hub/). + +When adding a Plugin Configuration to a Service, every request made by a client to +that Service will run said Plugin. If a Plugin needs to be tuned to different +values for some specific Consumers, you can do so by creating a separate +plugin instance that specifies both the Service and the Consumer, through the +`service` and `consumer` fields. + +Plugins can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.plugin_json }} +``` + +See the [Precedence](#precedence) section below for more details. + +#### Precedence + +A plugin will always be run once and only once per request. But the +configuration with which it will run depends on the entities it has been +configured for. + +Plugins can be configured for various entities, combination of entities, or +even globally. This is useful, for example, when you wish to configure a plugin +a certain way for most requests, but make _authenticated requests_ behave +slightly differently. + +Therefore, there exists an order of precedence for running a plugin when it has +been applied to different entities with different configurations. The rule of +thumb is: the more specific a plugin is with regards to how many entities it +has been configured on, the higher its priority. + +The complete order of precedence when a plugin has been configured multiple +times is: + +1. Plugins configured on a combination of: a Route, a Service, and a Consumer. + (Consumer means the request must be authenticated). +2. Plugins configured on a combination of a Route and a Consumer. + (Consumer means the request must be authenticated). +3. Plugins configured on a combination of a Service and a Consumer. + (Consumer means the request must be authenticated). +4. Plugins configured on a combination of a Route and a Service. +5. Plugins configured on a Consumer. + (Consumer means the request must be authenticated). +6. Plugins configured on a Route. +7. Plugins configured on a Service. +8. Plugins configured to run globally. + +**Example**: if the `rate-limiting` plugin is applied twice (with different +configurations): for a Service (Plugin config A), and for a Consumer (Plugin +config B), then requests authenticating this Consumer will run Plugin config B +and ignore A. However, requests that do not authenticate this Consumer will +fallback to running Plugin config A. Note that if config B is disabled +(its `enabled` flag is set to `false`), config A will apply to requests that +would have otherwise matched config B. + + +### List Plugins + +##### List All Plugins + +
/plugins
+ + +##### List Plugins Associated to a Specific Route + +
/routes/{route name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier or the `name` attribute of the Route whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Route will be listed. + + +##### List Plugins Associated to a Specific Service + +
/services/{service name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier or the `name` attribute of the Service whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Service will be listed. + + +##### List Plugins Associated to a Specific Consumer + +
/consumers/{consumer name or id}/plugins
+ +{:.indent} +Attributes | Description +---:| --- +`consumer name or id`
**required** | The unique identifier or the `name` attribute of the Consumer whose Plugins are to be retrieved. When using this endpoint, only Plugins associated to the specified Consumer will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.plugin_data }} + "next": "http://localhost:8001/plugins?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Plugin + +##### Retrieve Plugin + +
/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Route + +
/routes/{route name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`route name or id`
**required** | The unique identifier **or** the name of the Route to retrieve. +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Service + +
/services/{service name or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`service name or id`
**required** | The unique identifier **or** the name of the Service to retrieve. +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +##### Retrieve Plugin Associated to a Specific Consumer + +
/consumers/{consumer username or id}/plugins/{plugin id}
+ +{:.indent} +Attributes | Description +---:| --- +`consumer username or id`
**required** | The unique identifier **or** the username of the Consumer to retrieve. +`plugin id`
**required** | The unique identifier of the Plugin to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.plugin_json }} +``` + + +--- + +### Retrieve Enabled Plugins + +Retrieve a list of all installed plugins on the Kong node. + +
/plugins/enabled
+ +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "enabled_plugins": [ + "jwt", + "acl", + "cors", + "oauth2", + "tcp-log", + "udp-log", + "file-log", + "http-log", + "key-auth", + "hmac-auth", + "basic-auth", + "ip-restriction", + "request-transformer", + "response-transformer", + "request-size-limiting", + "rate-limiting", + "response-ratelimiting", + "aws-lambda", + "bot-detection", + "correlation-id", + "datadog", + "galileo", + "ldap-auth", + "loggly", + "statsd", + "syslog" + ] +} +``` + + +--- + +## Certificate Object + +A certificate object represents a public certificate, and can be optionally paired with the +corresponding private key. These objects are used by Kong to handle SSL/TLS termination for +encrypted requests, or for use as a trusted CA store when validating peer certificate of +client/service. Certificates are optionally associated with SNI objects to +tie a cert/key pair to one or more hostnames. + +If intermediate certificates are required in addition to the main +certificate, they should be concatenated together into one string according to +the following order: main certificate on the top, followed by any intermediates. + +Certificates can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.certificate_json }} +``` + +### List Certificates + +##### List All Certificates + +
/certificates
+ + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.certificate_data }} + "next": "http://localhost:8001/certificates?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Certificate + +##### Retrieve Certificate + +
/certificates/{certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. + + +##### Retrieve Certificate Associated to a Specific Upstream + +
/upstreams/{upstream name or id}/client_certificate
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream associated to the Certificate to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.certificate_json }} +``` + + +--- + +## CA Certificate Object + +A CA certificate object represents a trusted CA. These objects are used by Kong to +verify the validity of a client or server certificate. + +CA Certificates can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.ca_certificate_json }} +``` + +### List CA Certificates + +##### List All CA Certificates + +
/ca_certificates
+ + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.ca_certificate_data }} + "next": "http://localhost:8001/ca_certificates?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve CA Certificate + +##### Retrieve CA Certificate + +
/ca_certificates/{ca_certificate id}
+ +{:.indent} +Attributes | Description +---:| --- +`ca_certificate id`
**required** | The unique identifier of the CA Certificate to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.ca_certificate_json }} +``` + + +--- + +## SNI Object + +An SNI object represents a many-to-one mapping of hostnames to a certificate. +That is, a certificate object can have many hostnames associated with it; when +Kong receives an SSL request, it uses the SNI field in the Client Hello to +lookup the certificate object based on the SNI associated with the certificate. + +SNIs can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.sni_json }} +``` + +### List SNIs + +##### List All SNIs + +
/snis
+ + +##### List SNIs Associated to a Specific Certificate + +
/certificates/{certificate name or id}/snis
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate whose SNIs are to be retrieved. When using this endpoint, only SNIs associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.sni_data }} + "next": "http://localhost:8001/snis?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve SNI + +##### Retrieve SNI + +
/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to retrieve. + + +##### Retrieve SNI Associated to a Specific Certificate + +
/certificates/{certificate id}/snis/{sni name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. +`sni name or id`
**required** | The unique identifier **or** the name of the SNI to retrieve. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.sni_json }} +``` + + +--- + +## Upstream Object + +The upstream object represents a virtual hostname and can be used to loadbalance +incoming requests over multiple services (targets). So for example an upstream +named `service.v1.xyz` for a Service object whose `host` is `service.v1.xyz`. +Requests for this Service would be proxied to the targets defined within the upstream. + +An upstream also includes a [health checker][healthchecks], which is able to +enable and disable targets based on their ability or inability to serve +requests. The configuration for the health checker is stored in the upstream +object, and applies to all of its targets. + +Upstreams can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.upstream_json }} +``` + +### List Upstreams + +##### List All Upstreams + +
/upstreams
+ + +##### List Upstreams Associated to a Specific Certificate + +
/certificates/{certificate name or id}/upstreams
+ +{:.indent} +Attributes | Description +---:| --- +`certificate name or id`
**required** | The unique identifier or the `name` attribute of the Certificate whose Upstreams are to be retrieved. When using this endpoint, only Upstreams associated to the specified Certificate will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.upstream_data }} + "next": "http://localhost:8001/upstreams?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Retrieve Upstream + +##### Retrieve Upstream + +
/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to retrieve. + + +##### Retrieve Upstream Associated to a Specific Certificate + +
/certificates/{certificate id}/upstreams/{upstream name or id}
+ +{:.indent} +Attributes | Description +---:| --- +`certificate id`
**required** | The unique identifier of the Certificate to retrieve. +`upstream name or id`
**required** | The unique identifier **or** the name of the Upstream to retrieve. + + +##### Retrieve Upstream Associated to a Specific Target + +
/targets/{target host:port or id}/upstream
+ +{:.indent} +Attributes | Description +---:| --- +`target host:port or id`
**required** | The unique identifier **or** the host:port of the Target associated to the Upstream to be retrieved. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{{ page.upstream_json }} +``` + + +--- + +### Show Upstream Health for Node + +Displays the health status for all Targets of a given Upstream, or for +the whole Upstream, according to the perspective of a specific Kong node. +Note that, being node-specific information, making this same request +to different nodes of the Kong cluster may produce different results. +For example, one specific node of the Kong cluster may be experiencing +network issues, causing it to fail to connect to some Targets: these +Targets will be marked as unhealthy by that node (directing traffic from +this node to other Targets that it can successfully reach), but healthy +to all others Kong nodes (which have no problems using that Target). + +The `data` field of the response contains an array of Target objects. +The health for each Target is returned in its `health` field: + +* If a Target fails to be activated in the balancer due to DNS issues, + its status displays as `DNS_ERROR`. +* When [health checks][healthchecks] are not enabled in the Upstream + configuration, the health status for active Targets is displayed as + `HEALTHCHECKS_OFF`. +* When health checks are enabled and the Target is determined to be healthy, + either automatically or [manually](#set-target-as-healthy), + its status is displayed as `HEALTHY`. This means that this Target is + currently included in this Upstream's load balancer execution. +* When a Target has been disabled by either active or passive health checks + (circuit breakers) or [manually](#set-target-as-unhealthy), + its status is displayed as `UNHEALTHY`. The load balancer is not directing + any traffic to this Target via this Upstream. + +When the request query parameter `balancer_health` is set to `1`, the +`data` field of the response refers to the Upstream itself, and its `health` +attribute is defined by the state of all of Upstream's Targets, according +to the field `healthchecks.threshold`. + + +
/upstreams/{name or id}/health/
+ +{:.indent} +Attributes | Description +---:| --- +`name or id`
**required** | The unique identifier **or** the name of the Upstream for which to display Target health. + + +#### Request Querystring Parameters + +Attributes | Description +---:| --- +`balancer_health`
*optional* | If set to 1, Kong will return the health status of the Upstream itself. See the `healthchecks.threshold` property. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "total": 2, + "node_id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9", + "data": [ + { + "created_at": 1485524883980, + "id": "18c0ad90-f942-4098-88db-bbee3e43b27f", + "health": "HEALTHY", + "target": "127.0.0.1:20000", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 100 + }, + { + "created_at": 1485524914883, + "id": "6c6f34eb-e6c3-4c1f-ac58-4060e5bca890", + "health": "UNHEALTHY", + "target": "127.0.0.1:20002", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 200 + } + ] +} +``` + +If `balancer_health=1`: +``` +HTTP 200 OK +``` + +```json +{ + "data": { + "health": "HEALTHY", + "id": "07131005-ba30-4204-a29f-0927d53257b4" + }, + "next": null, + "node_id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9" +} +``` + + +--- + +## Target Object + +A target is an ip address/hostname with a port that identifies an instance of a backend +service. Every upstream can have many targets, and the targets can be +dynamically added. Changes are effectuated on the fly. + +Because the upstream maintains a history of target changes, the targets cannot +be deleted or modified. To disable a target, post a new one with `weight=0`; +alternatively, use the `DELETE` convenience method to accomplish the same. + +The current target object definition is the one with the latest `created_at`. + +Targets can be both [tagged and filtered by tags](#tags). + + +```json +{{ page.target_json }} +``` + +### List Targets + +##### List Targets Associated to a Specific Upstream + +
/upstreams/{upstream host:port or id}/targets
+ +{:.indent} +Attributes | Description +---:| --- +`upstream host:port or id`
**required** | The unique identifier or the `host:port` attribute of the Upstream whose Targets are to be retrieved. When using this endpoint, only Targets associated to the specified Upstream will be listed. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ +{{ page.target_data }} + "next": "http://localhost:8001/targets?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + + +--- + +### Set Target As Healthy + +Set the current health status of a target in the load balancer to "healthy" +in the entire Kong cluster. This sets the "healthy" status to all addresses +resolved by this target. + +This endpoint can be used to manually re-enable a target that was previously +disabled by the upstream's [health checker][healthchecks]. Upstreams only +forward requests to healthy nodes, so this call tells Kong to start using this +target again. + +This resets the health counters of the health checkers running in all workers +of the Kong node, and broadcasts a cluster-wide message so that the "healthy" +status is propagated to the whole Kong cluster. + + +
/upstreams/{upstream name or id}/targets/{target or id}/healthy
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream. +`target or id`
**required** | The host/port combination element of the target to set as healthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### Set Target As Unhealthy + +Set the current health status of a target in the load balancer to "unhealthy" +in the entire Kong cluster. This sets the "unhealthy" status to all addresses +resolved by this target. + +This endpoint can be used to manually disable a target and have it stop +responding to requests. Upstreams only forward requests to healthy nodes, so +this call tells Kong to start skipping this target. + +This call resets the health counters of the health checkers running in all +workers of the Kong node, and broadcasts a cluster-wide message so that the +"unhealthy" status is propagated to the whole Kong cluster. + +[Active health checks][active] continue to execute for unhealthy +targets. Note that if active health checks are enabled and the probe detects +that the target is actually healthy, it will automatically re-enable it again. +To permanently remove a target from the balancer, you should [delete a +target](#delete-target) instead. + + +
/upstreams/{upstream name or id}/targets/{target or id}/unhealthy
+ +{:.indent} +Attributes | Description +---:| --- +`upstream name or id`
**required** | The unique identifier **or** the name of the upstream. +`target or id`
**required** | The host/port combination element of the target to set as unhealthy, or the `id` of an existing target entry. + + +#### Response + +``` +HTTP 204 No Content +``` + + +--- + +### List All Targets + +Lists all targets of the upstream. Multiple target objects for the same +target may be returned, showing the history of changes for a specific target. +The target object with the latest `created_at` is the current definition. + + +
/upstreams/{name or id}/targets/all/
+ +{:.indent} +Attributes | Description +---:| --- +`name or id`
**required** | The unique identifier **or** the name of the upstream for which to list the targets. + + +#### Response + +``` +HTTP 200 OK +``` + +```json +{ + "total": 2, + "data": [ + { + "created_at": 1485524883980, + "id": "18c0ad90-f942-4098-88db-bbee3e43b27f", + "target": "127.0.0.1:20000", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 100 + }, + { + "created_at": 1485524914883, + "id": "6c6f34eb-e6c3-4c1f-ac58-4060e5bca890", + "target": "127.0.0.1:20002", + "upstream_id": "07131005-ba30-4204-a29f-0927d53257b4", + "weight": 200 + } + ] +} +``` + + +--- + +[clustering]: /{{page.kong_version}}/clustering +[cli]: /{{page.kong_version}}/cli +[active]: /{{page.kong_version}}/health-checks-circuit-breakers/#active-health-checks +[healthchecks]: /{{page.kong_version}}/health-checks-circuit-breakers +[secure-admin-api]: /{{page.kong_version}}/secure-admin-api +[proxy-reference]: /{{page.kong_version}}/proxy +[db-less]: /{{page.kong_version}}/db-less-and-declarative-config +[admin-api]: /{{page.kong_version}}/admin-api diff --git a/app/2.2.x/db-less-and-declarative-config.md b/app/2.2.x/db-less-and-declarative-config.md new file mode 100644 index 000000000000..a5aa6d9665bd --- /dev/null +++ b/app/2.2.x/db-less-and-declarative-config.md @@ -0,0 +1,330 @@ +--- +title: DB-less and Declarative Configuration +skip_read_time: true +--- + + +## Introduction + +Traditionally, Kong has always required a database, which could be either +Postgres or Cassandra, to store its configured entities such as Routes, +Services and Plugins. Kong uses its configuration file, `kong.conf`, to +specify the use of Postgres and Cassandra and its various settings. + +Kong 1.1 added the capability to run Kong without a database, using only +in-memory storage for entities: we call this **DB-less mode**. When running +Kong DB-less, the configuration of entities is done in a second configuration +file, in YAML or JSON, using **declarative configuration**. + +The combination of DB-less mode and declarative configuration has a number +of benefits: + +* reduced number of dependencies: no need to manage a database installation + if the entire setup for your use-cases fits in memory +* it is a good fit for automation in CI/CD scenarios: configuration for + entities can be kept in a single source of truth managed via a Git + repository +* it enables more deployment options for Kong + +## What Is Declarative Configuration + +If you are already familiar with the concept of declarative configuration, you +can skip this section. + +The key idea in declarative configuration is, as its name shows, the notion +that it is *declarative*, as opposed to an *imperative* style of +configuration. "Imperative" means that a configuration is given as a series of +orders: "do this, then do that". "Declarative" means that the configuration is +given all at once: "I declare this to be the state of the world". + +The Kong Admin API is an example of an imperative configuration tool. The +final state of the configuration is attained through a sequence of API calls: +one call to create a Service, another call to create a Route, another call to +add a Plugin, and so on. + +Performing the configuration incrementally like this has the undesirable +side-effect that *intermediate states* happen. In the above example, there is +a window of time in between creating a Route and adding the Plugin in which +the Route did not have the Plugin applied. + +A declarative configuration file, on the other hand, will contain the settings +for all desired entities in a single file, and once that file is loaded into +Kong, it replaces the entire configuration. When incremental changes are +desired, they are made to the declarative configuration file, which is then +reloaded in its entirety. At all times, the configuration described in the +file loaded into Kong is the configured state of the system. + +## Setting Up Kong in DB-less mode + +To use Kong in DB-less mode, set the `database` directive of `kong.conf` +to `off`. As usual, you can do this by editing `kong.conf` and setting +`database=off` or via environment variables. You can then start Kong +as usual: + +``` +$ export KONG_DATABASE=off +$ kong start -c kong.conf +``` + +Once Kong starts, access the `/` endpoint of the Admin API to verify that it +is running without a database. It will return the entire Kong configuration; +verify that `database` is set to `off`: + +``` +$ http :8001/ + +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Length: 6342 +Content-Type: application/json; charset=utf-8 +Date: Wed, 27 Mar 2019 15:24:58 GMT +Server: kong/2.1.0 +{ + "configuration:" { + ... + "database": "off", + ... + }, + ... + "version": "2.1.0" +} +``` + +Kong is running, but no declarative configuration was loaded yet. This +means that the configuration of this node is empty. There are no Routes, +Services or entities of any kind: + +``` +$ http :8001/routes + +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +Connection: keep-alive +Content-Length: 23 +Content-Type: application/json; charset=utf-8 +Date: Wed, 27 Mar 2019 15:30:02 GMT +Server: kong/2.1.0 + +{ + "data": [], + "next": null +} +``` + +## Creating a Declarative Configuration File + +To load entities into DB-less Kong, we need a declarative configuration +file. The following command will create a skeleton file to get you +started: + +``` +$ kong config -c kong.conf init +``` + +This command creates a `kong.yml` file in the current directory, +containing examples of the syntax for declaring entities and their +relationships. All examples in the generated file are commented-out +by default. You can experiment by uncommenting the examples +(removing the `#` markers) and modifying their values. + +## The Declarative Configuration Format + +The Kong declarative configuration format consists of lists of +entities and their attributes. This is a small yet complete +example that illustrates a number of features: + +```yaml +_format_version: "2.1" +_transform: true + +services: +- name: my-service + url: https://example.com + plugins: + - name: key-auth + routes: + - name: my-route + paths: + - / + +consumers: +- username: my-user + keyauth_credentials: + - key: my-key +``` + +The only mandatory piece of metadata is `_format_version: "2.1"`, which +specifies the version number of the declarative configuration syntax format. +This also matches the minimum version of Kong required to parse the file. + +The `_transform` metadata is an optional boolean (defaults to `true`), which +controls whether schema transformations will occur while importing. The rule +of thumb for using this field is: if you are importing plain-text credentials +(i.e. passwords), you likely want to set it to `true`, so that Kong will +encrypt/hash them before storing them in the database. If you are importing +**already hashed/encrypted** credentials, set `_transform` to `false` so that +the encryption does not happen twice. + +At the top level, you can specify any Kong entity, be it a core entity such as +`services` and `consumers` as in the above example, or custom entities created +by Plugins, such as `keyauth_credentials`. This makes the declarative +configuration format inherently extensible, and it is the reason why `kong +config` commands that process declarative configuration require `kong.conf` to +be available, so that the `plugins` directive is taken into account. + +When entities have a relationship, such as a Route that points to a Service, +this relationship can be specified via nesting. + +Only one-to-one relationships can be specified by nesting: a Plugin that is +applied to a Service can have its relationship depicted via nesting, as in the +example above. Relationships involving more than two entities, such as a +Plugin that is applied to both a Service and a Consumer must be done via a +top-level entry, where the entities can be identified by their primary keys +or identifying names (the same identifiers that can be used to refer to them +in the Admin API). This is an example of a plugin applied to a Service and +a Consumer: + +```yml +plugins: +- name: syslog + consumer: my-user + service: my-service +``` + +## Checking The Declarative Configuration File + +Once you are done editing the file, it is possible to check the syntax +for any errors before attempting to load it into Kong: + +``` +$ kong config -c kong.conf parse kong.yml + +parse successful +``` + +## Loading The Declarative Configuration File + +There are two ways to load a declarative configuration into Kong: via +`kong.conf` and via the Admin API. + +To load a declarative configuration at Kong start-up, use the +`declarative_config` directive in `kong.conf` (or, as usual to all `kong.conf` +entries, the equivalent `KONG_DECLARATIVE_CONFIG` environment variable). + +``` +$ export KONG_DATABASE=off +$ export KONG_DECLARATIVE_CONFIG=kong.yml +$ kong start -c kong.conf +``` + +Alternatively, you can load a declarative configuration into a running +Kong node via its Admin API, using the `/config` endpoint. The +following example loads `kong.yml` using HTTPie: + +``` +$ http :8001/config config=@kong.yml +``` + +The `/config` endpoint replaces the entire set of entities in memory +with the ones specified in the given file. + +## Using Kong in DB-less Mode + +There are a number of things to be aware of when using Kong in DB-less +mode. + +#### Memory Cache Requirements + +The entire configuration of entities must fit inside the Kong +cache. Make sure that the in-memory cache is configured appropriately: +see the `mem_cache_size` directive in `kong.conf`. + +#### No Central Database Coordination + +Since there is no central database, multiple Kong nodes have no +central coordination point and no cluster propagation of data: +nodes are completely independent of each other. + +This means that the declarative configuration should be loaded into each node +independently. Using the `/config` endpoint does not affect other Kong +nodes, since they have no knowledge of each other. + +#### Read-Only Admin API + +Since the only way to configure entities is via declarative configuration, +the endpoints for CRUD operations on entities are effectively read-only +in the Admin API when running Kong in DB-less mode. `GET` operations +for inspecting entities work as usual, but attempts to `POST`, `PATCH` +`PUT` or `DELETE` in endpoints such as `/services` or `/plugins` will return +`HTTP 405 Not Allowed`. + +This restriction is limited to what would be otherwise database operations. In +particular, using `POST` to set the health state of Targets is still enabled, +since this is a node-specific in-memory operation. + +#### Plugin Compatibility + +Not all Kong plugins are compatible with DB-less mode, since some of them +by design require a central database coordination and/or dynamic creation of +entities. + +##### Fully Compatible + +The following plugins only read from the database (most of them just to read +their initial config) so they are fully compatible with DB-less: + +* `aws-lambda` +* `azure-functions` +* `bot-detection` +* `correlation-id` +* `cors` +* `datadog` +* `file-log` +* `http-log` +* `tcp-log` +* `udp-log` +* `syslog` +* `ip-restriction` +* `prometheus` +* `zipkin` +* `request-transformer` +* `response-transformer` +* `request-termination` +* `kubernetes-sidecar-injector` + +##### Partial Compatibility + +Authentication plugins can be used insofar as the set of credentials +used is static and specified as part of the declarative configuration. +Admin API endpoints to dynamically create, update or delete credentials +are not available in DB-less mode. Plugins that fall into this +category are: + +* `acl` +* `basic-auth` +* `hmac-auth` +* `jwt` +* `key-auth` + +Rate limiting plugins bundled with Kong offer different policies for +storing and coordinating counters: a `local` policy which stores counters +the Nodes's memory, applying limits in a per-node fashion; a `redis` +policy which uses Redis as an external key-value store for coordinating +counters across nodes; and a `cluster` policy which uses the Kong database +as a central coordination point for cluster-wide limits. In DB-less mode, +the `local` and `redis` policies are available, and `cluster` cannot be +used. Plugins that fall into this category are: + +* `rate-limiting` +* `response-ratelimiting` + +The `pre-function` and `post-function` plugins for serverless can be used +in DB-less mode, with the caveat that if any configured functions attempt to +write to the database, the writes will fail. + +##### Not Compatible + +* `oauth2` - For its regular work, the plugin needs to both generate and delete + tokens, and commit those changes to the database, which is not compatible with + DB-less. diff --git a/app/2.2.x/getting-started/adding-consumers.md b/app/2.2.x/getting-started/adding-consumers.md new file mode 100644 index 000000000000..298bb533b41b --- /dev/null +++ b/app/2.2.x/getting-started/adding-consumers.md @@ -0,0 +1,98 @@ +--- +title: Adding Consumers +skip_read_time: true +--- + +
+ Before you start: +
    +
  1. Make sure you've installed Kong — It should only take a minute!
  2. +
  3. Make sure you've started Kong.
  4. +
  5. Also, make sure you've configured your Service in Kong.
  6. +
+
+ +In the last section, we learned how to add plugins to Kong, in this section +we're going to learn how to add consumers to your Kong instances. Consumers are +associated to individuals using your Service, and can be used for tracking, access +management, and more. + +**Note:** This section assumes you have [enabled][enabling-plugins] the +[key-auth][key-auth] plugin. If you haven't, you can either [enable the +plugin][enabling-plugins] or skip steps two and three. + +## 1. Create a Consumer through the RESTful API + +Lets create a user named `Jason` by issuing the following request: + +```bash +$ curl -i -X POST \ + --url http://localhost:8001/consumers/ \ + --data "username=Jason" +``` + +You should see a response similar to the one below: + +```http +HTTP/1.1 201 Created +Content-Type: application/json +Connection: keep-alive + +{ + "username": "Jason", + "created_at": 1428555626000, + "id": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9" +} +``` + +Congratulations! You've just added your first consumer to Kong. + +**Note:** Kong also accepts a `custom_id` parameter when [creating +consumers][API-consumers] to associate a consumer with your existing user +database. + +## 2. Provision key credentials for your Consumer + +Now, we can create a key for our recently created consumer `Jason` by +issuing the following request: + +```bash +$ curl -i -X POST \ + --url http://localhost:8001/consumers/Jason/key-auth/ \ + --data 'key=ENTER_KEY_HERE' +``` + +## 3. Verify that your Consumer credentials are valid + +We can now issue the following request to verify that the credentials of +our `Jason` Consumer is valid: + +```bash +$ curl -i -X GET \ + --url http://localhost:8000 \ + --header "Host: example.com" \ + --header "apikey: ENTER_KEY_HERE" +``` + +## Next Steps + +Now that we've covered the basics of adding Services, Routes, Consumers and enabling +Plugins, feel free to read more on Kong in one of the following documents: + +- [Configuration file Reference][configuration] +- [CLI Reference][CLI] +- [Proxy Reference][proxy] +- [Admin API Reference][API] +- [Clustering Reference][cluster] + +Questions? Issues? Contact us on one of the [Community Channels](/community) +for help! + +[key-auth]: /plugins/key-authentication +[API-consumers]: /{{page.kong_version}}/admin-api#create-consumer +[enabling-plugins]: /{{page.kong_version}}/getting-started/enabling-plugins +[configuration]: /{{page.kong_version}}/configuration +[CLI]: /{{page.kong_version}}/cli +[proxy]: /{{page.kong_version}}/proxy +[API]: /{{page.kong_version}}/admin-api +[cluster]: /{{page.kong_version}}/clustering diff --git a/app/2.2.x/getting-started/configuring-a-grpc-service.md b/app/2.2.x/getting-started/configuring-a-grpc-service.md new file mode 100644 index 000000000000..704ee154c912 --- /dev/null +++ b/app/2.2.x/getting-started/configuring-a-grpc-service.md @@ -0,0 +1,289 @@ +--- +title: Configuring a gRPC Service +skip_read_time: true +--- + +
+ Before you start: +
    +
  1. Make sure you've installed Kong — It should only take a minute!
  2. +
  3. Make sure you've started Kong.
  4. +
+
+ +Note: this guide assumes familiarity with gRPC; for learning how to set up +Kong with an upstream REST API, check out the [Configuring a Service guide][conf-service]. + +Starting with version 1.3, gRPC proxying is natively supported in Kong. In this +section, you'll learn how to configure Kong to manage your gRPC services. For the +purpose of this guide, we'll use [grpcurl][grpcurl] and [grpcbin][grpcbin] - they +provide a gRPC client and gRPC services, respectively. + +We will describe two setups: Single gRPC Service and Route and single gRPC Service +with multiple Routes. In the former, a single catch-all Route is configured, which +proxies all matching gRPC traffic to an upstream gRPC service; the latter demonstrates +how to use a Route per gRPC method. + +In Kong 1.3, gRPC support assumes gRPC over HTTP/2 framing. As such, make sure +you have at least one HTTP/2 proxy listener (check out the [Configuration Reference][configuration-rerefence] +for how to). In this guide, we will assume Kong is listening for HTTP/2 proxy +requests on port 9080. + +## 1. Single gRPC Service and Route + +Issue the following request to create a gRPC Service (assuming your gRPC +server is listening in localhost, port 15002): + +```bash +$ curl -XPOST localhost:8001/services \ + --data name=grpc \ + --data protocol=grpc \ + --data host=localhost \ + --data port=15002 +``` + +Issue the following request to create a gRPC route: + +```bash +$ curl -XPOST localhost:8001/services/grpc/routes \ + --data protocols=grpc \ + --data name=catch-all \ + --data paths=/ +``` + +Using the [grpcurl][grpcurl] command line client, issue the following gRPC +request: + +```bash +$ grpcurl -v -d '{"greeting": "Kong 1.3!"}' \ + -plaintext localhost:9080 hello.HelloService.SayHello +``` + +The response should resemble the following: + +``` +Resolved method descriptor: +rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse ); + +Request metadata to send: +(empty) + +Response headers received: +content-type: application/grpc +date: Tue, 16 Jul 2019 21:37:36 GMT +server: openresty/1.15.8.1 +via: kong/1.2.1 +x-kong-proxy-latency: 0 +x-kong-upstream-latency: 0 + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response trailers received: +(empty) +Sent 1 request and received 1 response +``` + +Notice that Kong response headers, such as `via` and `x-kong-proxy-latency`, were +inserted in the response. + +## 2. Single gRPC Service with Multiple Routes + +Building on top of the previous example, let's create a few more routes, for +individual gRPC methods. + +The gRPC "HelloService" service being used in this example exposes a few different +methods, as can be seen in [its protobuf file][protobuf]. We will create individual +routes for its "SayHello" and LotsOfReplies methods. + +Create a Route for "SayHello": + +```bash +$ curl -XPOST localhost:8001/services/grpc/routes \ + --data protocols=grpc \ + --data paths=/hello.HelloService/SayHello \ + --data name=say-hello +``` + +Create a Route for "LotsOfReplies": + +```bash +$ curl -XPOST localhost:8001/services/grpc/routes \ + --data protocols=grpc \ + --data paths=/hello.HelloService/LotsOfReplies \ + --data name=lots-of-replies +``` + +With this setup, gRPC requests to the "SayHello" method will match the first +Route, while requests to "LotsOfReplies" will be routed to the latter. + +Issue a gRPC request to the "SayHello" method: + +```bash +$ grpcurl -v -d '{"greeting": "Kong 1.3!"}' \ + -H 'kong-debug: 1' -plaintext \ + localhost:9080 hello.HelloService.SayHello +``` + +(Notice we are sending a header `kong-debug`, which causes Kong to insert +debugging information in response headers.) + +The response should look like: + +``` +Resolved method descriptor: +rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse ); + +Request metadata to send: +kong-debug: 1 + +Response headers received: +content-type: application/grpc +date: Tue, 16 Jul 2019 21:57:00 GMT +kong-route-id: 390ef3d1-d092-4401-99ca-0b4e42453d97 +kong-service-id: d82736b7-a4fd-4530-b575-c68d94c3493a +kong-service-name: s1 +server: openresty/1.15.8.1 +via: kong/1.2.1 +x-kong-proxy-latency: 0 +x-kong-upstream-latency: 0 + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response trailers received: +(empty) +Sent 1 request and received 1 response +``` + +Notice the Route ID should refer to the first route we created. + +Similarly, let's issue a request to the "LotsOfReplies" gRPC method: + +```bash +$ grpcurl -v -d '{"greeting": "Kong 1.3!"}' \ + -H 'kong-debug: 1' -plaintext \ + localhost:9080 hello.HelloService.LotsOfReplies +``` + +The response should look like the following: + +``` +Resolved method descriptor: +rpc LotsOfReplies ( .hello.HelloRequest ) returns ( stream .hello.HelloResponse ); + +Request metadata to send: +kong-debug: 1 + +Response headers received: +content-type: application/grpc +date: Tue, 30 Jul 2019 22:21:40 GMT +kong-route-id: 133659bb-7e88-4ac5-b177-bc04b3974c87 +kong-service-id: 31a87674-f984-4f75-8abc-85da478e204f +kong-service-name: grpc +server: openresty/1.15.8.1 +via: kong/1.2.1 +x-kong-proxy-latency: 14 +x-kong-upstream-latency: 0 + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response contents: +{ + "reply": "hello Kong 1.3!" +} + +Response trailers received: +(empty) +Sent 1 request and received 10 responses +``` + +Notice that the `kong-route-id` response header now carries a different value +and refers to the second Route created in this page. + +**Note:** +Some gRPC clients (typically CLI clients) issue ["gRPC Reflection Requests"][grpc-reflection] +as a means of determining what methods a server exports and how those methods are called. +Said requests have a particular path; for example, `/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo` +is a valid reflection path. As with any proxy request, Kong needs to know how to +route these; in the current example, they would be routed to the catch-all route +(whose path is `/`, matching any path). If no route matches the gRPC reflection +request, Kong will respond, as expected, with a `404 Not Found` response. + +## 3. Enabling Plugins + +Kong 1.3 gRPC support is compatible with Logging and Observability plugins; for +example, let's try out the [File Log][file-log] plugin with gRPC. + +Issue the following request to enable File Log on the "SayHello" route: + +```bash +$ curl -X POST localhost:8001/routes/say-hello/plugins \ + --data name=file-log \ + --data config.path=grpc-say-hello.log +``` + +Follow the output of the log as gRPC requests are made to "SayHello": + +``` +$ tail -f grpc-say-hello.log +{"latencies":{"request":8,"kong":5,"proxy":3},"service":{"host":"localhost","created_at":1564527408,"connect_timeout":60000,"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","protocol":"grpc","name":"grpc","read_timeout":60000,"port":15002,"updated_at":1564527408,"write_timeout":60000,"retries":5},"request":{"querystring":{},"size":"46","uri":"\/hello.HelloService\/SayHello","url":"http:\/\/localhost:9080\/hello.HelloService\/SayHello","headers":{"host":"localhost:9080","content-type":"application\/grpc","kong-debug":"1","user-agent":"grpc-go\/1.20.0-dev","te":"trailers"},"method":"POST"},"client_ip":"127.0.0.1","tries":[{"balancer_latency":0,"port":15002,"balancer_start":1564527732522,"ip":"127.0.0.1"}],"response":{"headers":{"kong-route-id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","content-type":"application\/grpc","connection":"close","kong-service-name":"grpc","kong-service-id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","kong-route-name":"say-hello","via":"kong\/1.2.1","x-kong-proxy-latency":"5","x-kong-upstream-latency":"3"},"status":200,"size":"298"},"route":{"id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","updated_at":1564527431,"protocols":["grpc"],"created_at":1564527431,"service":{"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c"},"name":"say-hello","preserve_host":false,"regex_priority":0,"strip_path":false,"paths":["\/hello.HelloService\/SayHello"],"https_redirect_status_code":426},"started_at":1564527732516} +{"latencies":{"request":3,"kong":1,"proxy":1},"service":{"host":"localhost","created_at":1564527408,"connect_timeout":60000,"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","protocol":"grpc","name":"grpc","read_timeout":60000,"port":15002,"updated_at":1564527408,"write_timeout":60000,"retries":5},"request":{"querystring":{},"size":"46","uri":"\/hello.HelloService\/SayHello","url":"http:\/\/localhost:9080\/hello.HelloService\/SayHello","headers":{"host":"localhost:9080","content-type":"application\/grpc","kong-debug":"1","user-agent":"grpc-go\/1.20.0-dev","te":"trailers"},"method":"POST"},"client_ip":"127.0.0.1","tries":[{"balancer_latency":0,"port":15002,"balancer_start":1564527733555,"ip":"127.0.0.1"}],"response":{"headers":{"kong-route-id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","content-type":"application\/grpc","connection":"close","kong-service-name":"grpc","kong-service-id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c","kong-route-name":"say-hello","via":"kong\/1.2.1","x-kong-proxy-latency":"1","x-kong-upstream-latency":"1"},"status":200,"size":"298"},"route":{"id":"e49f2df9-3e8e-4bdb-8ce6-2c505eac4ab6","updated_at":1564527431,"protocols":["grpc"],"created_at":1564527431,"service":{"id":"74a95d95-fbe4-4ddb-a448-b8faf07ece4c"},"name":"say-hello","preserve_host":false,"regex_priority":0,"strip_path":false,"paths":["\/hello.HelloService\/SayHello"],"https_redirect_status_code":426},"started_at":1564527733554} +``` + +[enabling-plugins]: /{{page.kong_version}}/getting-started/enabling-plugins +[conf-service]: /{{page.kong_version}}/getting-started/configuring-a-service +[configuration-reference]: /{{page.kong_version}}/configuration-reference +[grpc-reflection]: https://github.com/grpc/grpc/blob/master/doc/server_reflection_tutorial.md +[grpcbin]: https://github.com/moul/grpcbin +[grpcurl]: https://github.com/fullstorydev/grpcurl +[protobuf]: https://raw.githubusercontent.com/moul/pb/master/hello/hello.proto +[file-log]: /plugins/file-log +[zipkin]: /plugins/zipkin diff --git a/app/2.2.x/getting-started/configuring-a-service.md b/app/2.2.x/getting-started/configuring-a-service.md new file mode 100644 index 000000000000..8ef7ac2ac091 --- /dev/null +++ b/app/2.2.x/getting-started/configuring-a-service.md @@ -0,0 +1,138 @@ +--- +title: Configuring a Service +skip_read_time: true +--- + +
+ Before you start: +
    +
  1. Make sure you've installed Kong — It should only take a minute!
  2. +
  3. Make sure you've started Kong.
  4. +
+
+ +In this section, you'll be adding an API to Kong. In order to do this, you'll +first need to add a _Service_; that is the name Kong uses to refer to the upstream APIs and microservices +it manages. + +For the purpose of this guide, we'll create a Service pointing to the [Mockbin API][mockbin]. Mockbin is +an "echo" type public website which returns the requests it gets back to the requester, as responses. This +makes it helpful for learning how Kong proxies your API requests. + +Before you can start making requests against the Service, you will need to add a _Route_ to it. +Routes specify how (and _if_) requests are sent to their Services after they reach Kong. A single +Service can have many Routes. + +After configuring the Service and the Route, you'll be able to make requests through Kong using them. + +Kong exposes a [RESTful Admin API][API] on port `:8001`. Kong's configuration, including adding Services and +Routes, is made via requests on that API. + +## 1. Add your Service using the Admin API + +Issue the following cURL request to add your first Service (pointing to the [Mockbin API][mockbin]) +to Kong: + +```bash +$ curl -i -X POST \ + --url http://localhost:8001/services/ \ + --data 'name=example-service' \ + --data 'url=http://mockbin.org' +``` + +You should receive a response similar to: + +```http +HTTP/1.1 201 Created +Content-Type: application/json +Connection: keep-alive + +{ + "host":"mockbin.org", + "created_at":1519130509, + "connect_timeout":60000, + "id":"92956672-f5ea-4e9a-b096-667bf55bc40c", + "protocol":"http", + "name":"example-service", + "read_timeout":60000, + "port":80, + "path":null, + "updated_at":1519130509, + "retries":5, + "write_timeout":60000 +} +``` + + +## 2. Add a Route for the Service + +```bash +$ curl -i -X POST \ + --url http://localhost:8001/services/example-service/routes \ + --data 'hosts[]=example.com' +``` + +The answer should be similar to: + +```http +HTTP/1.1 201 Created +Content-Type: application/json +Connection: keep-alive + +{ + "created_at":1519131139, + "strip_path":true, + "hosts":[ + "example.com" + ], + "preserve_host":false, + "regex_priority":0, + "updated_at":1519131139, + "paths":null, + "service":{ + "id":"79d7ee6e-9fc7-4b95-aa3b-61d2e17e7516" + }, + "methods":null, + "protocols":[ + "http", + "https" + ], + "id":"f9ce2ed7-c06e-4e16-bd5d-3a82daef3f9d" +} +``` + +Kong is now aware of your Service and ready to proxy requests. + +## 3. Forward your requests through Kong + +Issue the following cURL request to verify that Kong is properly forwarding +requests to your Service. Note that [by default][proxy-port] Kong handles proxy +requests on port `:8000`: + +```bash +$ curl -i -X GET \ + --url http://localhost:8000/ \ + --header 'Host: example.com' +``` + +A successful response means Kong is now forwarding requests made to +`http://localhost:8000` to the `url` we configured in step #1, +and is forwarding the response back to us. Kong knows to do this through +the header defined in the above cURL request: + +
    +
  • Host: <given host>
  • +
+ +
+ +## Next Steps + +Now that you've added your Service to Kong, let's learn how to enable plugins. + +Go to [Enabling Plugins ›][enabling-plugins] + +[API]: /{{page.kong_version}}/admin-api +[enabling-plugins]: /{{page.kong_version}}/getting-started/enabling-plugins +[proxy-port]: /{{page.kong_version}}/configuration/#nginx-section +[mockbin]: https://mockbin.com/ diff --git a/app/2.2.x/getting-started/enabling-plugins.md b/app/2.2.x/getting-started/enabling-plugins.md new file mode 100644 index 000000000000..daca256d3c25 --- /dev/null +++ b/app/2.2.x/getting-started/enabling-plugins.md @@ -0,0 +1,75 @@ +--- +title: Enabling Plugins +skip_read_time: true +--- + +
+ Before you start: +
    +
  1. Make sure you've installed Kong - It should only take a minute!
  2. +
  3. Make sure you've started Kong.
  4. +
  5. Also, make sure you've configured your Service in Kong.
  6. +
+
+ +In this section, you'll learn how to configure Kong plugins. One of the core +principles of Kong is its extensibility through [plugins][plugins]. Plugins +allow you to easily add new features to your Service or make it easier to +manage. + +In the steps below, you will configure the [key-auth][key-auth] plugin to add +authentication to your Service. Prior to the addition of this plugin, **all** +requests to your Service would be proxied upstream. Once you add and configure this +plugin, **only** requests with the correct key(s) will be proxied - all +other requests will be rejected by Kong, thus protecting your upstream service +from unauthorized use. + + +## 1. Configure the key-auth plugin + +To configure the key-auth plugin for the Service you configured in Kong, +issue the following cURL request: + +```bash +$ curl -i -X POST \ + --url http://localhost:8001/services/example-service/plugins/ \ + --data 'name=key-auth' +``` + +**Note:** This plugin also accepts a `config.key_names` parameter, which +defaults to `['apikey']`. It is a list of headers and parameters names (both +are supported) that are supposed to contain the apikey during a request. + +## 2. Verify that the plugin is properly configured + +Issue the following cURL request to verify that the [key-auth][key-auth] +plugin was properly configured on the Service: + +```bash +$ curl -i -X GET \ + --url http://localhost:8000/ \ + --header 'Host: example.com' +``` + +Since you did not specify the required `apikey` header or parameter, the +response should be `401 Unauthorized`: + +```http +HTTP/1.1 401 Unauthorized +... + +{ + "message": "No API key found in request" +} +``` + +## Next Steps + +Now that you've configured the **key-auth** plugin lets learn how to add +consumers to your Service so we can continue proxying requests through Kong. + +Go to [Adding Consumers ›][adding-consumers] + +[key-auth]: /plugins/key-authentication +[plugins]: /plugins +[adding-consumers]: /{{page.kong_version}}/getting-started/adding-consumers diff --git a/app/2.2.x/getting-started/introduction.md b/app/2.2.x/getting-started/introduction.md new file mode 100644 index 000000000000..bf6fcd69667d --- /dev/null +++ b/app/2.2.x/getting-started/introduction.md @@ -0,0 +1,32 @@ +--- +title: Welcome to Kong +skip_read_time: true +--- + +
+ Before you start: Make sure you've installed Kong — It should only take a minute! +
+ +Before going further into Kong, make sure you understand its [purpose and philosophy](/about). Once you are confident with the concept of API Gateways, this guide is going to take you through a quick introduction on how to use Kong and perform basic operations such as: + +- [Running your own Kong instance][quickstart] +- [Adding and consuming Services][configuring-a-service] +- [Installing plugins on Kong][enabling-plugins] + +## What is Kong, technically? + +You’ve probably heard that Kong is built on Nginx, leveraging its stability and efficiency. But how is this possible exactly? + +To be more precise, Kong is a Lua application running in Nginx and made possible by the [lua-nginx-module](https://github.com/openresty/lua-nginx-module). Instead of compiling Nginx with this module, Kong is distributed along with [OpenResty](https://openresty.org/), which already includes lua-nginx-module. OpenResty is *not* a fork of Nginx, but a bundle of modules extending its capabilities. + +This sets the foundations for a pluggable architecture, where Lua scripts (referred to as *plugins*) can be enabled and executed at runtime. Because of this, we like to think of Kong as **a paragon of microservice architecture**: at its core, it implements database abstraction, routing and plugin management. Plugins can live in separate code bases and be injected anywhere into the request lifecycle, all in a few lines of code. + +## Next Steps + +Now, lets get familiar with learning how to "start" and "stop" Kong. + +Go to [5-minute quickstart with Kong ›][quickstart] + +[quickstart]: /{{page.kong_version}}/getting-started/quickstart +[configuring-a-service]: /{{page.kong_version}}/getting-started/configuring-a-service +[enabling-plugins]: /{{page.kong_version}}/getting-started/enabling-plugins diff --git a/app/2.2.x/getting-started/quickstart.md b/app/2.2.x/getting-started/quickstart.md new file mode 100644 index 000000000000..419659a83265 --- /dev/null +++ b/app/2.2.x/getting-started/quickstart.md @@ -0,0 +1,81 @@ +--- +title: 5-minute Quickstart +skip_read_time: true +--- + +
+ Before you start: Make sure you've + installed Kong — It should only take a minute! +
+ +In this section, you'll learn how to manage your Kong instance. First, we'll +have you start Kong in order to give you access to the RESTful Admin +interface, through which you manage your Services, Routes, Consumers, and more. Data sent +through the Admin API is stored in Kong's [datastore][datastore-section] (Kong +supports PostgreSQL and Cassandra). + +## 1. Start Kong + +Issue the following command to prepare your datastore by running the Kong +migrations: + +```bash +$ kong migrations bootstrap [-c /path/to/kong.conf] +``` + +You should see a message that tells you Kong has successfully migrated your +database. If not, you probably incorrectly configured your database +connection settings in your configuration file. + +Now let's [start][CLI] Kong: + +```bash +$ kong start [-c /path/to/kong.conf] +``` + +**Note:** The CLI accepts a configuration option (`-c /path/to/kong.conf`) +allowing you to point to [your own configuration][configuration-loading]. + +## 2. Verify that Kong has started successfully + +If everything went well, you should see a message (`Kong started`) +informing you that Kong is running. + +By default, Kong listens on the following ports: + +- `:8000` on which Kong listens for incoming HTTP traffic from your + clients, and forwards it to your upstream services. +- `:8443` on which Kong listens for incoming HTTPS traffic. This port has a + similar behavior as the `:8000` port, except that it expects HTTPS + traffic only. This port can be disabled via the configuration file. +- `:8001` on which the [Admin API][API] used to configure Kong listens. +- `:8444` on which the Admin API listens for HTTPS traffic. + +## 3. Stop Kong + +As needed you can stop the Kong process by issuing the following +[command][CLI]: + +```bash +$ kong stop +``` + +## 4. Reload Kong + +Issue the following command to [reload][CLI] Kong without downtime: + +```bash +$ kong reload +``` + +## Next Steps + +Now that you have Kong running you can interact with the Admin API. + +To begin, go to [Configuring a Service ›][configuring-a-service] + +[configuration-loading]: /{{page.kong_version}}/configuration/#configuration-loading +[CLI]: /{{page.kong_version}}/cli +[API]: /{{page.kong_version}}/admin-api +[datastore-section]: /{{page.kong_version}}/configuration/#datastore-section +[configuring-a-service]: /{{page.kong_version}}/getting-started/configuring-a-service diff --git a/app/2.2.x/go.md b/app/2.2.x/go.md new file mode 100644 index 000000000000..3f5ee5964c5c --- /dev/null +++ b/app/2.2.x/go.md @@ -0,0 +1,224 @@ +--- +title: Go language support +--- + +## Introduction + +Since version 2.0, Kong can be extended with the Go programming language. This +Guide introduces Go plugins and provides instructions on how to write and use +them. + +### New Concepts + +#### Go Plugin Server + +In order for Kong to run Go plugins, it employs a sidecar process: the +[go-pluginserver][go-pluginserver]. The role of this process is to dynamically +load a Go plugin and execute its code on demand, based on communication +with Kong (performed through a Unix domain socket). Kong is responsible for +managing the life cycle of the go-pluginserver, and, as you will see below, it +only needs to know where to find the go-pluginserver's executable to do so. + +#### The go-pdk + +The [go-pdk][go-pdk] allows your Go plugins to access functionality provided +by the [Kong PDK][kong-pdk]. In order to use it, you need to import add +`"github.com/Kong/go-pdk"` to the list of packages imported by your plugin. +The `kong` parameter received on the phase handler methods is the entry point +for the Go PDK functions. Most of these functions work the same as the corresponding +functions in the Lua PDK. + +Check out the [go-pdk](https://pkg.go.dev/github.com/Kong/go-pdk) GoDoc page for +the reference documentation of the Go PDK. + +### Prerequisites + +In order to use Go plugins, you need the following: + +1. A Go compiler, which can be obtained from your Operating System's package +manager, or directly at the [Go Downloads page](https://golang.org/dl/); + +2. The `go-pluginserver` executable, built as instructed in the following section. +By default, Kong will expect it in `/usr/local/bin`; however, this location can +be customized with the `go_pluginserver_exe` property in the Kong configuration +file - or via environment variables, like any other Kong configuration property; + +3. Set the `go_plugins_dir` variable in the Kong configuration file to a valid directory +where your Go plugins will be installed; the default value `off` value disables +Go support; + +4. Add your compiled Go plugins to the directory specified in the previous step +(`go_plugins_dir`); + +5. As with custom Lua plugins, make sure to add your Go plugin name to the `plugins` +property, which effectively means Kong will load your plugin; + +6. Enable the plugin in the usual way, either via Admin API or a declarative +configuration file. + +### Building the Go Plugin Server and your Go Plugins + +The Go Plugin Server is a typical Go application. Leveraging Go Modules, it +can be built in the following way: + +1. Initialize a `go.mod` file for your Kong Go Plugin project: +``` +$ go mod init kong-go-plugin +go: creating new go.mod: module kong-go-plugin +``` + +2. Import the Go Plugin Server as a dependency: +``` +$ go get -d -v github.com/Kong/go-pluginserver +go: github.com/Kong/go-pluginserver upgrade => v0.5.0 +go: downloading github.com/Kong/go-pluginserver v0.5.0 +go: downloading github.com/Kong/go-pdk v0.5.0 +go: downloading github.com/ugorji/go v1.1.7 +go: downloading github.com/ugorji/go/codec v1.1.7 +``` +This will, by default, select the latest version available, registering it +into the `go.mod` file and adding all its dependencies into `go.sum`. Note that, +in this example, the latest go-pluginserver version available was `v0.5.0` and +it also pinned the go-pdk version it uses. + +3. Build the Go Plugin Server with the following command, which will result in +a `go-pluginserver` executable being placed in the current directory: +``` +$ go build github.com/Kong/go-pluginserver +``` +**Note**: The following step builds a Go plugin. For the purpose of this tutorial, +we will assume its name is `go-hello`. You can find example Go plugins [here][go-plugins]. + +4. Build your Go plugin with the following command, which will result in a +`.so` file being placed in the current directory: +``` +go build -buildmode plugin go-hello.go +``` + +#### Environment Consistency Constraints + +Golang development is well known for its low entry barrier and ease of +deployment. Even complex programs written in Go can be distributed as a single +executable that you can copy anywhere and run directly. + +To make this possible, the compiler generates statically-linked executables by +default. A significant drawback of this choice is that it makes extending a +"finished" Go program very difficult. There are several ways around this +limitation, but most of them involve some form of interprocess communication. +Since this is well supported by the language and basic libraries, it's usually +a very good solution, but this isn't always the case. + +The extension strategy chosen for Kong is common in other languages: a plugin +is a dynamically loaded module. To allow this, instead of producing fully +static programs, the executable and plugins depend on the system libraries. + +This is a relatively recent feature in Golang (introduced in Go 1.8, as the +"plugin" build mode), and has some rough edges in tooling and deployability. +In particular, it's essential that the loading executable (`go-pluginserver` in +our case) and the plugins have exactly the same linking behaviour. This involves: +* The same version of any common libraries, including: + * `Kong/go-pdk` + * All standard Go libraries (like `fmt`, `rpc`, `reflect`, etc) + * OS libraries, like `libpthread`, `libc`, `ld-xxxx`, etc. +* The exact same version of the Go compiler +* The same Go environment variables like `$GOROOT` and `$GOPATH` + +Typically, environment inconsistency issues manifest with error messages like +the following: +``` +failed to open plugin kong: plugin.Open("/path/go-plugins/go-hello"): plugin was built with a different version of package github.com/Kong/go-pdk/bridge +``` + +By following the build steps in the section above, building the go-pluginserver +and plugins in the same environment, consistency is guaranteed. + +## Developing Go Plugins + +This section shows you how to write a custom Go plugin. It will be useful to +cross-reference a real Go plugin; see an example [here][go-hello]. + +### Development + +To write a Kong plugin in Go, you need to: + +1. Define a structure type to hold configuration; +2. Write a `New()` function to create instances of your structure; +3. Add methods on that structure to handle phases; +4. Compile your Go plugin (check out the previous section to learn how to build +your plugins); +5. Put the resulting library (the `.so` file) into the `go_plugins_dir` directory, +as explained in the Prerequisites section. + +**Note**: check out [this repository](https://github.com/Kong/go-plugins) +for example Go plugins. + +#### 1. Configuration Structure + +Plugins written in Lua define a schema to specify how to read and validate +configuration data coming from the datastore or the Admin API. Since Go is a +statically type language, all that specification is handled by defining a +configuration structure. + +``` +type MyConfig struct { + Path string + Reopen bool +} +``` + +Public fields (that is, those starting with a capital letter) will be filled +with configuration data. If you want them to have a different name in the +datastore, add field tags as defined in the `encoding/json` package: + +``` +type MyConfig struct { + Path string `json:my_file_path` + Reopen bool `json:reopen` +} +``` + +#### 2. New() Constructor + +Your plugin must define a function called New that creates an instance of this type +and returns as an `interface{}`. In most cases it’s just this: + +``` +func New() interface{} { + return &MyConfig{} +} +``` + +You can add more fields to the structure and they’ll be passed around, but +there’s no guarantees about the lifetime or quantity of configuration +instances. + +#### 3. Phase Handlers + +Similarly to Kong Lua plugins, you can implement custom logic to be executed at +various points of the request processing life-cycle. For example, to execute +custom Go code in the "access" phase, define a function named `Access`: +``` +func (conf *MyConfig) Access (kong *pdk.PDK) { + ... +} +``` + +The phases you can implement custom logic for are, and the expected function +signature is the same for all of them: +- `Certificate` +- `Rewrite` +- `Access` +- `Response` +- `Preread` +- `Log` + +Similar to Lua plugins, the presence of the `Response` handler automatically enables the "buffered proxy" mode. + +--- + +[go-pluginserver]: https://github.com/Kong/go-pluginserver +[go-pluginserver-makefile]: https://github.com/Kong/go-pluginserver/blob/master/Makefile +[go-plugins]: https://github.com/Kong/go-plugins +[go-pdk]: https://github.com/Kong/go-pdk +[kong-pdk]: https://docs.konghq.com/latest/plugin-development/ +[go-hello]: https://github.com/Kong/go-plugins/blob/master/go-hello.go diff --git a/app/2.2.x/health-checks-circuit-breakers.md b/app/2.2.x/health-checks-circuit-breakers.md new file mode 100644 index 000000000000..e980ca04759e --- /dev/null +++ b/app/2.2.x/health-checks-circuit-breakers.md @@ -0,0 +1,362 @@ +--- +title: Health Checks and Circuit Breakers Reference +--- + +## Introduction + +You can make an API proxied by Kong use a [ring-balancer][ringbalancer], configured +by adding an [upstream][upstream] entity that contains one or more [target][ringtarget] +entities, each target pointing to a different IP address (or hostname) and +port. The ring-balancer will balance load among the various targets, and based +on the [upstream][upstream] configuration, will perform health checks on the targets, +making them as healthy or unhealthy whether they are responsive or not. The +ring-balancer will then only route traffic to healthy targets. + +Kong supports two kinds of health checks, which can be used separately or in +conjunction: + +* **active checks**, where a specific HTTP or HTTPS endpoint in the target is +periodically requested and the health of the target is determined based on its +response; + +* **passive checks** (also known as **circuit breakers**), where Kong analyzes +the ongoing traffic being proxied and determines the health of targets based +on their behavior responding requests. + +## Defining healthy and unhealthy + +### Targets + +The objective of the health checks functionality is to dynamically mark +targets as healthy or unhealthy, **for a given Kong node**. There is +no cluster-wide synchronization of health information: each Kong node +determines the health of its targets separately. This is desirable since at a +given point one Kong node may be able to connect to a target successfully +while another node is failing to reach it: the first node will consider +it healthy, while the second will mark it as unhealthy and start routing +traffic to other targets of the upstream. + +Either an active probe (on active health checks) or a proxied request +(on passive health checks) produces data which is used to determine +whether a target is healthy or unhealthy. A request may produce a TCP +error, timeout, or produce an HTTP status code. Based on this +information, the health checker updates a series of internal counters: + +* If the returned status code is one configured as "healthy", it will +increment the "Successes" counter for the target and clear all its other +counters; +* If it fails to connect, it will increment the "TCP failures" counter +for the target and clear the "Successes" counter; +* If it times out, it will increment the "timeouts" counter +for the target and clear the "Successes" counter; +* If the returned status code is one configured as "unhealthy", it will +increment the "HTTP failures" counter for the target and clear the "Successes" counter. + +If any of the "TCP failures", "HTTP failures" or "timeouts" counters reaches +their configured threshold, the target will be marked as unhealthy. + +If the "Successes" counter reaches its configured threshold, the target will be +marked as healthy. + +The list of which HTTP status codes are "healthy" or "unhealthy", and the +individual thresholds for each of these counters are configurable on a +per-upstream basis. Below, we have an example of a configuration for an +Upstream entity, showcasing the default values of the various fields +available for configuring health checks. A description of each +field is included in the [Admin API][addupstream] reference documentation. + +```json +{ + "name": "service.v1.xyz", + "healthchecks": { + "active": { + "concurrency": 10, + "healthy": { + "http_statuses": [ 200, 302 ], + "interval": 0, + "successes": 0 + }, + "http_path": "/", + "timeout": 1, + "unhealthy": { + "http_failures": 0, + "http_statuses": [ 429, 404, 500, 501, + 502, 503, 504, 505 ], + "interval": 0, + "tcp_failures": 0, + "timeouts": 0 + } + }, + "passive": { + "healthy": { + "http_statuses": [ 200, 201, 202, 203, + 204, 205, 206, 207, + 208, 226, 300, 301, + 302, 303, 304, 305, + 306, 307, 308 ], + "successes": 0 + }, + "unhealthy": { + "http_failures": 0, + "http_statuses": [ 429, 500, 503 ], + "tcp_failures": 0, + "timeouts": 0 + } + }, + "threshold": 0 + }, + "slots": 10 +} +``` + +If an upstream is unhealthy (the available capacity % is less than the configured +threshold), Kong will respond to requests to the upstream with +`503 Service Unavailable`. + +Note: + +1. health checks operate only on [*active* targets][targetobject] and do not + modify the *active* status of a target in the Kong database. +2. unhealthy targets will not be removed from the loadbalancer, and hence will + not have any impact on the balancer layout when using the hashing algorithm + (they will just be skipped). +3. The [DNS caveats][dnscaveats] and [balancer caveats][balancercaveats] + also apply to health checks. If using hostnames for the targets, then make + sure the DNS server always returns the full set of IP addresses for a name, + and does not limit the response. *Failing to do so might lead to health + checks not being executed.* + +### Upstreams + +Along with health check functionality on individual targets, Upstreams also +have a notion of health. The health of an Upstream is determined based on the +status of its Targets. + +Configuration of the Upstream's health is done though the property +`healthchecks.threshold`. This is a percentage of minimum available target +"weight" (capacity) for the Upstream to be considered healthy. + +Here is a simple example: + +- Assume an Upstream configured with `healthchecks.threshold=55`. +- It has 5 targets, each with `weight=100`, so the total weight in the ring-balancer is 500. + +When failures start to occur, the circuit-breaker for the first target trips. +It is now considered unhealthy. This means that in the ring-balancer, 20% of +the capacity is now unhealthy (100 weight out of 500). This is still above the +threshold of 55, so the remaining targets will serve the traffic of the failed +one. + +When a second failure occurs, another target fails, and another 100 weight is lost +as unhealthy. Now the ring-balancer operates at 60% of its capacity, but still +within the configured threshold. + +If we assume that the 2 failures occured due to a system overload, we can now assume +that the remaining 60% will also not be able to cope with the full load and soon a third +node will fail, reducing healthy capacity to 40%. At this point, the Upstream health +will be less than its threshold, and it will be marked as unhealthy itself. + +Once it enters an unhealthy state, the Upstream will only return errors. This lets the +targets/services recover from the cascading failure they were experiencing. + +Once the Targets start recovering and the Upstream's available capacity passes the +threshold again, the health status of the ring-balancer will automatically be updated. + + +## Types of health checks + +### Active health checks + +Active health checks, as the name implies, actively probe targets for +their health. When active health checks are enabled in an upstream entity, +Kong will periodically issue HTTP or HTTPS requests to a configured path at each target +of the upstream. This allows Kong to automatically enable and disable targets +in the balancer based on the [probe results](#healthy-and-unhealthy-targets). + +The periodicity of active health checks can be configured separately for +when a target is healthy or unhealthy. If the `interval` value for either +is set to zero, the checking is disabled at the corresponding scenario. +When both are zero, active health checks are disabled altogether. + +
+Note: Active health checks currently only support HTTP/HTTPS targets. They +do not apply to Upstreams assigned to Services with the protocol attribute set to "tcp" or "tls". +
+ +[Back to top](#introduction) + +### Passive health checks (circuit breakers) + +Passive health checks, also known as circuit breakers, are +checks performed based on the requests being proxied by Kong (HTTP/HTTPS/TCP), +with no additional traffic being generated. When a target becomes +unresponsive, the passive health checker will detect that and mark +the target as unhealthy. The ring-balancer will start skipping this +target, so no more traffic will be routed to it. + +Once the problem with a target is solved and it is ready to receive +traffic again, the Kong administrator can manually inform the +health checker that the target should be enabled again, via an +Admin API endpoint: + +```bash +$ curl -i -X POST http://localhost:8001/upstreams/my_upstream/targets/10.1.2.3:1234/healthy +HTTP/1.1 204 No Content +``` + +This command will broadcast a cluster-wide message so that the "healthy" +status is propagated to the whole [Kong cluster][clustering]. This will cause Kong nodes to +reset the health counters of the health checkers running in all workers of the +Kong node, allowing the ring-balancer to route traffic to the target again. + +Passive health checks have the advantage of not producing extra +traffic, but they are unable to automatically mark a target as +healthy again: the "circuit is broken", and the target needs to +be re-enabled again by the system administrator. + + +[Back to top](#introduction) + +## Summary of pros and cons + +* Active health checks can automatically re-enable a target in the +ring balancer as soon as it is healthy again. Passive health checks cannot. +* Passive health checks do not produce additional traffic to the +target. Active health checks do. +* An active health checker demands a known URL with a reliable status response +in the target to be configured as a probe endpoint (which may be as +simple as `"/"`). Passive health checks do not demand such configuration. +* By providing a custom probe endpoint for an active health checker, +an application may determine its own health metrics and produce a status +code to be consumed by Kong. Even though a target continues to serve +traffic which looks healthy to the passive health checker, +it would be able to respond to the active probe with a failure +status, essentially requesting to be relieved from taking new traffic. + +It is possible to combine the two modes. For example, one can enable +passive health checks to monitor the target health based solely on its +traffic, and only use active health checks while the target is unhealthy, +in order to re-enable it automatically. + +## Enabling and disabling health checks + +### Enabling active health checks + +To enable active health checks, you need to specify the configuration items +under `healthchecks.active` in the [Upstream object][upstreamobjects] configuration. You +need to specify the necessary information so that Kong can perform periodic +probing on the target, and how to interpret the resulting information. + +You can use the `healthchecks.active.type` field to specify whether to perform +HTTP or HTTPS probes (setting it to `"http"` or `"https"`), or by simply +testing if the connection to a given host and port is successful +(setting it to `"tcp"`). + +For configuring the probe, you need to specify: + +* `healthchecks.active.http_path` - The path that should be used when +issuing the HTTP GET request to the target. The default value is `"/"`. +* `healthchecks.active.timeout` - The connection timeout limit for the +HTTP GET request of the probe. The default value is 1 second. +* `healthchecks.active.concurrency` - Number of targets to check concurrently +in active health checks. + +You also need to specify positive values for intervals, for running +probes: + +* `healthchecks.active.healthy.interval` - Interval between active health +checks for healthy targets (in seconds). A value of zero indicates that active +probes for healthy targets should not be performed. +* `healthchecks.active.unhealthy.interval` - Interval between active health +checks for unhealthy targets (in seconds). A value of zero indicates that active +probes for unhealthy targets should not be performed. + +This allows you to tune the behavior of the active health checks, whether you +want probes for healthy and unhealthy targets to run at the same interval, or +one to be more frequent than the other. + +If you are using HTTPS healthchecks, you can also specify the following +fields: + +* `healthchecks.active.https_verify_certificate` - Whether to check the +validity of the SSL certificate of the remote host when performing active +health checks using HTTPS. +* `healthchecks.active.https_sni` - The hostname to use as an SNI +(Server Name Identification) when performing active health checks +using HTTPS. This is particularly useful when Targets are configured +using IPs, so that the target host's certificate can be verified +with the proper SNI. + +Note that failed TLS verifications will increment the "TCP failures" counter; +the "HTTP failures" refer only to HTTP status codes, whether probes are done +through HTTP or HTTPS. + +Finally, you need to configure how Kong should interpret the probe, by setting +the various thresholds on the [health +counters](#healthy-and-unhealthy-targets), which, once reached will trigger a +status change. The counter threshold fields are: + +* `healthchecks.active.healthy.successes` - Number of successes in active +probes (as defined by `healthchecks.active.healthy.http_statuses`) to consider +a target healthy. +* `healthchecks.active.unhealthy.tcp_failures` - Number of TCP failures +or TLS verification failures in active probes to consider a target unhealthy. +* `healthchecks.active.unhealthy.timeouts` - Number of timeouts in active +probes to consider a target unhealthy. +* `healthchecks.active.unhealthy.http_failures` - Number of HTTP failures in +active probes (as defined by `healthchecks.active.unhealthy.http_statuses`) to +consider a target unhealthy. + +### Enabling passive health checks + +Passive health checks do not feature a probe, as they work by interpreting +the ongoing traffic that flows from a target. This means that to enable +passive checks you only need to configure its counter thresholds: + +* `healthchecks.passive.healthy.successes` - Number of successes in proxied +traffic (as defined by `healthchecks.passive.healthy.http_statuses`) to +consider a target healthy, as observed by passive health checks. This needs to +be positive when passive checks are enabled so that healthy traffic resets the +unhealthy counters. +* `healthchecks.passive.unhealthy.tcp_failures` - Number of TCP failures in +proxied traffic to consider a target unhealthy, as observed by passive health +checks. +* `healthchecks.passive.unhealthy.timeouts` - Number of timeouts in proxied +traffic to consider a target unhealthy, as observed by passive health checks. +* `healthchecks.passive.unhealthy.http_failures` - Number of HTTP failures in +proxied traffic (as defined by `healthchecks.passive.unhealthy.http_statuses`) +to consider a target unhealthy, as observed by passive health checks. + +### Disabling health checks + +In all counter thresholds and intervals specified in the `healthchecks` +configuration, setting a value to zero means that the functionality the field +represents is disabled. Setting a probe interval to zero disables a probe. +Likewise, you can disable certain types of checks by setting their counter +thresholds to zero. For example, to not consider timeouts when performing +healthchecks, you can set both `timeouts` fields (for active and passive +checks) to zero. This gives you a fine-grained control of the behavior of the +health checker. + +In summary, to completely disable active health checks for an upstream, you +need to set both `healthchecks.active.healthy.interval` and +`healthchecks.active.unhealthy.interval` to `0`. + +To completely disable passive health checks, you need to set all counter +thresholds under `healthchecks.passive` for its various counters to zero. + +All counter thresholds and intervals in `healthchecks` are zero by default, +meaning that health checks are completely disabled by default in newly created +upstreams. + +[Back to top](#introduction) + +[ringbalancer]: /{{page.kong_version}}/loadbalancing#ring-balancer +[ringtarget]: /{{page.kong_version}}/loadbalancing#target +[upstream]: /{{page.kong_version}}/loadbalancing#upstream +[targetobject]: /{{page.kong_version}}/admin-api#target-object +[addupstream]: /{{page.kong_version}}/admin-api#add-upstream +[clustering]: /{{page.kong_version}}/clustering +[upstreamobjects]: /{{page.kong_version}}/admin-api#upstream-objects +[balancercaveats]: /{{page.kong_version}}/loadbalancing#balancing-caveats +[dnscaveats]: /{{page.kong_version}}/loadbalancing#dns-caveats diff --git a/app/2.2.x/hybrid-mode.md b/app/2.2.x/hybrid-mode.md new file mode 100644 index 000000000000..a9dab9a0f0ce --- /dev/null +++ b/app/2.2.x/hybrid-mode.md @@ -0,0 +1,396 @@ +--- +title: Hybrid Mode Deployment +--- + + +## Introduction + +Traditionally, Kong has always required a database, which could be either +Postgres or Cassandra, to store its configured entities such as Routes, +Services and Plugins. In Kong 1.1 we added the capability to run Kong without +a database, using only in-memory storage for entities: we call this [**DB-less mode**][db-less]. + +In Kong 2.0, we introduced a new method of deploying Kong which is +called the **Hybrid mode**, also known as **Control Plane / Data Plane Separation (CP/DP)**. + +In this mode Kong nodes in a cluster are separated into two roles: Control Plane (CP), where configuration is managed and the Admin API is served from, +and Data Plane (DP), which serves traffic for the proxy. Each DP node is connected to one of the CP nodes. Instead of accessing the +database contents directly in the traditional deployment method, the DP nodes maintains +connection with CP nodes, and receives the latest configuration. + +Deploying using Hybrid mode has a number of benefits: + +* Drastically reduce the amount of traffic on the database, since only CP nodes need a + direct connection to the database. +* Increased security, in an event where one of the DP nodes gets intruded, an attacker + won't be able to affect other nodes in the Kong cluster. +* Easiness of management, since an admin will only need to interact with the CP nodes to control + and monitor the status of the entire Kong cluster. + +## Configuration Properties + +Hybrid Mode introduces the following configuration properties: + +Parameter | Description +--- | --- +`cluster_listen` *Optional* | List of addresses and ports on which the Control Plane will listen for incoming Data Plane connections. Defaults to `0.0.0.0:8005`. Note this port is always protected with Mutual TLS (mTLS) encryption. Ignored on Data Plane nodes. +`cluster_control_plane` *Required* | Address and port that the Data Plane nodes use to connect to the Control Plane. Must point to the port configured using the `cluster_listen` property on the Control Plane node. Ignored on Control Plane nodes. +`cluster_mtls` *Optional* | One of `"shared"` or `"pki"`. Indicates whether Hybrid Mode will use a shared certificate/key pair for CP/DP mTLS or if PKI mode will be used. Defaults to `"shared"`. See below sections for differences in mTLS modes. + +The following properties are used differently between "shared" and "PKI" modes: + +Parameter | Description | Shared Mode | PKI Mode +--- | --- | --- | --- +`cluster_cert` and `cluster_cert_key` *Required* | Certificate/key pair used for mTLS between CP/DP nodes. | Same between CP/DP nodes. | Unique certificate for each node, generated from the CA specified by `cluster_ca_cert`. +`cluster_ca_cert` *Required in PKI mode* | The trusted CA certificate file in PEM format used to verify the `cluster_cert`. | *Ignored* | CA certificate used to verify `cluster_cert`, same between CP/DP nodes. *Required* +`cluster_server_name` *Required in PKI mode* | The SNI Server Name presented by the DP node mTLS handshake. | *Ignored* | In PKI mode the DP nodes will also verify that the Common Name (CN) or Subject Alternative Name (SAN) inside certificate presented by CP matches the `cluster_server_name` value. + +## Topology + +![Example Hybrid Mode Topology](/assets/images/docs/hybrid-mode.png "Example Hybrid Mode Topology") + +## Generating Certificate/Key Pair + +Before using the Hybrid Mode, it is necessary to have a shared certificate/key pair generated +so that the communication security between CP and DP nodes can be established. + +This certificate/key pair is shared by both CP and DP nodes, mutual TLS handshake (mTLS) is used +for authentication so the actual private key is never transferred on the network. + +
+ Protect the Private Key! Ensure the private key file can only be accessed by + Kong nodes belonging to the cluster. If key is suspected to be compromised it is necessary to + re-generate and replace certificate and keys on all the CP/DP nodes. +
+ +To create a certificate/key pair: + +``` +kong hybrid gen_cert +``` + +This will generate `cluster.crt` and `cluster.key` files and save them to the current directory. +By default it is valid for 3 years, but can be set longer or shorter with the `--days` option. + +See `kong hybrid --help` for more usage information. + +The `cluster.crt` and `cluster.key` files need to be transferred to both Kong CP and DP nodes. +Observe proper permission setting on the key file to ensure it can only be read by Kong. + +## Setting Up Kong Control Plane Nodes + +Starting the Control Plane is fairly simple. Aside from the database configuration +which is the same as today, we need to specify the "role" of the node to "control\_plane". +This will cause Kong to listen on `0.0.0.0:8005` by default for Data Plane +connections. The `8005` port on the Control Plane will need to be +accessible by all the Data Plane it controls through any firewalls you may have +in place. + +In addition, the `cluster_cert` and `cluster_cert_key` configuration need to point to +the certificate/key pair that was generated above. + +``` +KONG_ROLE=control_plane KONG_CLUSTER_CERT=cluster.crt KONG_CLUSTER_CERT_KEY=cluster.key kong start +``` + +Or in `kong.conf`: + +``` +role = control_plane +cluster_cert = cluster.crt +cluster_cert_key = cluster.key +``` + +Note that Control Plane still needs a database (Postgres or Cassandra) to store the +"source of truth" configurations, although the database never needs to be access by +Data Plane nodes. You may run more than a single Control Plane nodes to provide load balancing +and redundancy as long as they points to the same backend database. + +## PKI mode + +Starting in Kong 2.1, the Hybrid cluster can use certificates signed by a central certificate authority (CA). +This mode can be activated by setting `cluster_mtls` to `"pki"` in `kong.conf`. The default value is `"shared"`. + +In PKI mode, the Control Plane and Data Plane don't need to use the same `cluster_cert` and `cluster_cert_key`. +Instead, Kong validates both sides by checking if they are from the same CA. This eliminates the risk of +transporting private keys around. + +{% navtabs %} +{% navtab CA Certificate Example %} +Typically, a CA certificate will look like this: + +``` +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 5d:29:73:bf:c3:da:5f:60:69:da:73:ed:0e:2e:97:6f:7f:4c:db:4b + Signature Algorithm: ecdsa-with-SHA256 + Issuer: O = Kong Inc., CN = Hybrid Root CA + Validity + Not Before: Jul 7 12:36:10 2020 GMT + Not After : Jul 7 12:36:40 2023 GMT + Subject: O = Kong Inc., CN = Hybrid Root CA + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:df:49:9f:39:e6:2c:52:9f:46:7a:df:ae:7b:9b: + 87:1e:76:bb:2e:1d:9c:61:77:07:e5:8a:ba:34:53: + 3a:27:4c:1e:76:23:b4:a2:08:80:b4:1f:18:7a:0b: + 79:de:ea:8c:23:94:e6:2f:57:cf:27:b4:0a:52:59: + 90:2c:2b:86:03 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 8A:0F:07:61:1A:0F:F4:B4:5D:B7:F3:B7:28:D1:C5:4B:81:A2:B9:25 + X509v3 Authority Key Identifier: + keyid:8A:0F:07:61:1A:0F:F4:B4:5D:B7:F3:B7:28:D1:C5:4B:81:A2:B9:25 + + Signature Algorithm: ecdsa-with-SHA256 + 30:45:02:20:68:3c:d1:f3:63:a2:aa:b4:59:c9:52:af:33:b7: + 3f:ca:3a:2b:1c:9d:87:0c:c0:47:ff:a2:c4:af:3e:b0:36:29: + 02:21:00:86:ce:d0:fc:ba:92:e9:59:16:1c:c3:b2:11:11:ed: + 01:5d:16:49:d0:f9:0c:1d:35:0d:40:ba:19:98:31:76:57 +``` +{% endnavtab %} + +{% navtab CA Certificate on CP %} +An example CP certificate will be: + +``` +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 18:cc:a3:6b:aa:77:0a:69:c6:d5:ff:12:be:be:c0:ac:5c:ff:f1:1e + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN = Hybrid Intermediate CA + Validity + Not Before: Jul 31 00:59:29 2020 GMT + Not After : Oct 29 00:59:59 2020 GMT + Subject: CN = control-plane.kong.yourcorp.tld + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:f8:3a:a9:d2:e2:79:19:19:f3:1c:58:a0:23:60: + 78:04:1f:7e:e2:bb:60:d2:29:50:ad:7c:9b:8e:22: + 1c:54:c2:ce:68:b8:6c:8a:f6:92:9d:0c:ce:08:d3: + aa:0c:20:67:41:32:18:63:c9:dd:50:31:60:d6:8b: + 8d:f9:7b:b5:37 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Subject Key Identifier: + 70:C7:F0:3B:CD:EB:8D:1B:FF:6A:7C:E0:A4:F0:C6:4C:4A:19:B8:7F + X509v3 Authority Key Identifier: + keyid:16:0D:CF:92:3B:31:B0:61:E5:AB:EE:91:42:B9:60:56:0A:88:92:82 + + X509v3 Subject Alternative Name: + DNS:control-plane.kong.yourcorp.tld, DNS:alternate-control-plane.kong.yourcorp.tld + X509v3 CRL Distribution Points: + + Full Name: + URI:https://crl-service.yourcorp.tld/v1/pki/crl + + Signature Algorithm: ecdsa-with-SHA256 + 30:44:02:20:5d:dd:ec:a8:4f:e7:5b:7d:2f:3f:ec:b5:40:d7: + de:5e:96:e1:db:b7:73:d6:84:2e:be:89:93:77:f1:05:07:f3: + 02:20:16:56:d9:90:06:cf:98:07:87:33:dc:ef:f4:cc:6b:d1: + 19:8f:64:ee:82:a6:e8:e6:de:57:a7:24:82:72:82:49 +``` +{% endnavtab %} + +{% navtab CA Certificate on DP %} +An example DP certificate will be: + +``` +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4d:8b:eb:89:a2:ed:b5:29:80:94:31:e4:94:86:ce:4f:98:5a:ad:a0 + Signature Algorithm: ecdsa-with-SHA256 + Issuer: CN = Hybrid Intermediate CA + Validity + Not Before: Jul 31 00:57:01 2020 GMT + Not After : Oct 29 00:57:31 2020 GMT + Subject: CN = kong-dp-ce39edecp.service + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:19:51:80:4c:6d:8c:a8:05:63:42:71:a2:9a:23: + 34:34:92:c6:2a:d3:e5:15:6e:36:44:85:64:0a:4c: + 12:16:82:3f:b7:4c:e1:a1:5a:49:5d:4c:5e:af:3c: + c1:37:e7:91:e2:b5:52:41:a0:51:ac:13:7b:cc:69: + 93:82:9b:2f:e2 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Subject Key Identifier: + 25:82:8C:93:85:35:C3:D6:34:CF:CB:7B:D6:14:97:46:84:B9:2B:87 + X509v3 Authority Key Identifier: + keyid:16:0D:CF:92:3B:31:B0:61:E5:AB:EE:91:42:B9:60:56:0A:88:92:82 + X509v3 CRL Distribution Points: + + Full Name: + URI:https://crl-service.yourcorp.tld/v1/pki/crl + + Signature Algorithm: ecdsa-with-SHA256 + 30:44:02:20:65:2f:5e:30:f7:a4:28:14:88:53:58:c5:85:24: + 35:50:25:c9:fe:db:2f:72:9f:ad:7d:a0:67:67:36:32:2b:d2: + 02:20:2a:27:7d:eb:75:a6:ee:65:8b:f1:66:a4:99:32:56:7c: + ad:ca:3a:d5:50:8f:cf:aa:6d:c2:1c:af:a4:ca:75:e8 +``` +{% endnavtab %} +{% endnavtabs %} + +> **Note:** Certificates on CP and DP must contain the `TLS Web Server Authentication` and +`TLS Web Client Authentication` as X509v3 Extended Key Usage extension, respectively. + +Kong doesn't validate the CommonName (CN) in the DP certificate; it can take an arbitrary value. + +Set the following configuration parameters in `kong.conf` on the Control Plane: + +``` +cluster_mtls = pki +cluster_ca_cert = /path/to/ca-cert.crt +cluster_cert = control-plane.crt +cluster_cert_key = control-plane.key +``` + +`cluster_ca_cert` specifies the root CA certificate for `cluster_cert` and `cluster_cert_key`. This +certificate must be the root CA certificate and not any of an intermediate CA. +Kong allows at most `3` levels of intermediate CAs to be used between the root CA and the cluster certificate. + +Set the following configuration parameters in `kong.conf` on the Data Plane: + +``` +cluster_mtls = pki +cluster_server_name = control-plane.kong.yourcorp.tld +cluster_cert = data-plane.crt +cluster_cert_key = data-plane.crt +``` + +`cluster_server_name` specifies the SNI (Server Name Indication extension) to use for Data Plane +connections to the Control Plane through TLS. When not set, Data Plane will use `kong_clustering` as the SNI. + + +## Starting Data Plane Nodes + +Now we have a Control Plane running, it is not much useful if no Data Plane nodes are +talking to it and serving traffic (remember Control Plane nodes can not be used +for proxying). To start the Data Plane, all we need to do is to specify the "role" +to "data\_plane", give it the address and port of where the Control Plane can be reached +and the node automatically connects and syncs itself up with the current configuration. + +Similar to the CP config above, `cluster_cert` and `cluster_cert_key` configuration need to +point to the same files as the CP has. In addition the `cluster.crt` file need to be listed +as trusted by OpenResty through the `lua_ssl_trusted_certificate` configuration. If you +have already specified a different `lua_ssl_trusted_certificate`, then adding the content +of `cluster.crt` into that file will achieve the same result. + +**Note:** In this release of the Hybrid Mode, the Data Plane receives updates from the Control +Plane via a format that is similar to the Declarative Config, therefore the `database` +property has to be set to `off` for Kong to start up properly. + +``` +KONG_ROLE=data_plane KONG_CLUSTER_CONTROL_PLANE=control-plane.example.com:8005 KONG_CLUSTER_CERT=cluster.crt KONG_CLUSTER_CERT_KEY=cluster.key KONG_LUA_SSL_TRUSTED_CERTIFICATE=cluster.crt KONG_DATABASE=off kong start +``` + +Or in `kong.conf`: + +``` +role = data_plane +cluster_control_plane = control-plane.example.com:8005 +database = off +cluster_cert = cluster.crt +cluster_cert_key = cluster.key +lua_ssl_trusted_certificate = cluster.crt +``` + +## Checking the status of the cluster + +You may want to check the status of the Kong cluster from time to time, such as +checking to see the which nodes are actively receiving config updates from +Control Plane, or when was it last updated. This can be achieved by using the +Control Plane's new Cluster Status API: + +``` +# on Control Plane node +http :8001/clustering/data_planes + + +{ + "data": [ + { + "config_hash": "a9a166c59873245db8f1a747ba9a80a7", + "hostname": "data-plane-2", + "id": "ed58ac85-dba6-4946-999d-e8b5071607d4", + "ip": "192.168.10.3", + "last_seen": 1580623199, + "status": "connected" + }, + { + "config_hash": "a9a166c59873245db8f1a747ba9a80a7", + "hostname": "data-plane-1", + "id": "ed58ac85-dba6-4946-999d-e8b5071607d4", + "ip": "192.168.10.4", + "last_seen": 1580623200, + "status": "connected" + } + ], + "next": null +} +``` + +The Cluster Status API provides helpful information such as +the name of the node and last time it synced with the Control Plane, as +well as config version currently running on them. + +## Managing the cluster using Control Plane nodes + +Once the nodes are setup, use the Admin API on the Control Plane as usual, +those changes will be synced and updated on the Data Plane nodes +automatically within seconds. + +## Fault tolerance + +A valid question you may ask is: What would happen if Control Plane nodes are down, +will the Data Plane keep functioning? The answer is yes. Data plane caches +the latest configuration it received from the Control Plane on the local disk. +In case Control Plane stops working, Data Plane will keep serving requests using +cached configurations. It does so while constantly trying to reestablish communication +with the Control Plane. + +This means that the Data Plane nodes can be restarted while the Control Plane +is down, and still proxy traffic normally. + +## Limitations + +### Plugins compatibility + +This version of Hybrid Mode uses declarative config as the config sync format which +means it has the same limitations as declarative config as of today. Please refer +to the [Plugin Compatibility section][plugin-compat] +of declarative config documentation for more information. + +--- + +[plugin-compat]: /{{page.kong_version}}/db-less-and-declarative-config#plugin-compatibility +[db-less]: /{{page.kong_version}}/db-less-and-declarative-config diff --git a/app/2.2.x/index.md b/app/2.2.x/index.md new file mode 100644 index 000000000000..01ffdffdbb4a --- /dev/null +++ b/app/2.2.x/index.md @@ -0,0 +1,103 @@ +--- +title: Documentation for Kong Gateway +is_homepage: true +--- + +
+
+

Installation

+

You can install Kong Gateway on most Linux distributions and MacOS. We even provide the source so you can compile it yourself.

+ Install Kong Gateway → +
+ +
+

Getting Started

+

Whether you’re a Community or an Enterprise Kong user, use this guide to familiarize yourself with Kong concepts and learn how to use important features and capabilities.

+ Get started → +
+ +
+

DB-less & Declarative Configuration

+

Learn how to leverage the declarative configuration format for using Kong Gateway without a database, using in-memory storage only.

+ Read the tutorial → +
+ +
+

Kong for Kubernetes

+

Get Started with Kong for Kubernetes.

+ Learn More → +
+ +
+

Upgrade Guide

+

Already using Kong Gateway, and wanting to upgrade? Here's the step-by-step guide.

+ Read the upgrade guide → +
+ +
+

5-Minute Quickstart Guide

+

Check out this guide if you just need the absolute basics: start Kong Gateway, add a Service, enable plugins, and add consumers.

+ Start using Kong Gateway → +
+ +
+

Configuration Reference

+

Want to further optimize your Kong Gateway cluster, database, or configure NGINX? Dive into the configuration.

+ Start configuration → +
+ +
+

CLI Reference

+

Want a better understanding of the CLI tool and its options? Browse the detailed command reference.

+ Use the CLI → +
+ +
+

Admin API Reference

+

Ready to learn the underlying interface? Browse the Admin API reference to learn how to start making requests.

+ Explore the interface → +
+ +
+

Proxy Reference

+

Learn every way to configure proxies for your Services, serve them over SSL, or use WebSockets.

+ Read the Proxy Reference → +
+ +
+

Load Balancing Reference

+

Learn how to load balance traffic through replicas of your upstream services.

+ Read the Load balancing Reference → +
+ +
+

Health Checks & Circuit Breakers

+

Let Kong Gateway monitor the availability of your services and adjust its load balancing accordingly.

+ Learn about health checks and circuit breakers → +
+ +
+

Clustering

+

If you are starting more than one node, you must use clustering to make sure all the nodes belong to the same cluster.

+ Read the clustering reference → +
+ +
+

Write Your Own Plugins

+

Looking for something Kong Gateway does not do for you? Easy: write it as a plugin. Learn how to write your own plugins for Kong Gateway.

+ Read the plugin development guide → +
+ +
+

Go Plugins

+

You can also write plugins using the Go programming language. Here's how to get started.

+ Read the guide → +
+ +
+

Hybrid Mode

+

Get started with Hybrid Mode, through which you can configure nodes with dedicated roles: you can have Control Plane nodes using a database and Data Plane nodes using DB-less mode.

+ Read the tutorial → +
+ +
diff --git a/app/2.2.x/kong-for-kubernetes/changelog.md b/app/2.2.x/kong-for-kubernetes/changelog.md new file mode 100644 index 000000000000..b843673cfc02 --- /dev/null +++ b/app/2.2.x/kong-for-kubernetes/changelog.md @@ -0,0 +1,15 @@ +--- +title: Kong for Kubernetes Changelog +toc: false +--- + +Kong for Kubernetes comprises of two components: + +* Kong Gateway +* Controller, which actively configures Kong based on the configuration defined in Kubernetes + + +The changelog for both these components can be found in the following Github repositories: + +* Kong: +* Controller: diff --git a/app/2.2.x/kong-for-kubernetes/index.md b/app/2.2.x/kong-for-kubernetes/index.md new file mode 100644 index 000000000000..cb925b3e54de --- /dev/null +++ b/app/2.2.x/kong-for-kubernetes/index.md @@ -0,0 +1,14 @@ +--- +title: Kong for Kubernetes +--- + +**Kong for Kubernetes includes the following features:** + +- Kong is configured dynamically and responds to the changes in your infrastructure. +- Kong is deployed onto Kubernetes with a Controller, which is responsible for configuring Kong. +- All of Kong’s configuration is done using Kubernetes resources, stored in Kubernetes’ data-store (etcd). +- Use the power of kubectl (or any custom tooling around kubectl) to configure Kong and get benefits of all Kubernetes, such as declarative configuration, cloud-provider agnostic deployments, RBAC, reconciliation of desired state, and elastic scalability. +- Kong is configured using a combination of Ingress Resource and Custom Resource Definitions(CRDs). +- DB-less by default, meaning Kong has the capability of running without a database and using only memory storage for entities. + +Kong for Kubernetes control diagram diff --git a/app/2.2.x/kong-for-kubernetes/install.md b/app/2.2.x/kong-for-kubernetes/install.md new file mode 100644 index 000000000000..78862db60b8f --- /dev/null +++ b/app/2.2.x/kong-for-kubernetes/install.md @@ -0,0 +1,75 @@ +--- +title: Install Kong for Kubernetes +--- + +This installation topic guides you through installing and deploying Kong for Kubernetes (K4K8S), then directs you to the documentation for configuring and using the product. + +## Prerequisites +- **Kubernetes cluster**: You can use [Minikube](https://kubernetes.io/docs/setup/minikube/) or a [GKE](https://cloud.google.com/kubernetes-engine/) cluster. Kong is compatible with all distributions of Kubernetes. +- **kubectl access**: You should have `kubectl` installed and configured to communicate to your Kubernetes cluster. + + +## Installing Kong for Kubernetes +Use one of the following installation methods to install Kong for Kubernetes: +- [YAML manifests](#yaml-manifests) +- [Helm Chart](#helm-chart) +- [Kustomize](#kustomize) + + +### YAML manifests +To deploy Kong via `kubectl`, use: + +``` +kubectl apply -f https://bit.ly/kong-ingress-dbless +``` + +> Important! This is not a production-grade deployment. +Adjust “knobs” based on your use case: +- Replicas: Ensure that you are running multiple instances of Kong to protect against outages from a single node failure. +- Performance optimization: Adjust memory settings of Kong and tailor your deployment to your use case. +- Load-balancer: Ensure that you are running a Layer-4 or TCP based balancer in front of Kong. This allows Kong to serve a TLS certificate and integrate with a cert-manager. + + +### Helm Chart +Kong has an official Helm Chart. To deploy Kong onto your Kubernetes cluster with Helm, use: + +``` +$ helm repo add kong https://charts.konghq.com +$ helm repo update + +# Helm 2 +$ helm install kong/kong + +# Helm 3 +$ helm install kong/kong --generate-name --set ingressController.installCRDs=false +``` + +For more information about using a Helm Chart, see chart +[documentation](https://github.com/Kong/charts/blob/main/charts/kong/README.md). + +### Kustomize +Kong’s manifests for Kubernetes can be declaratively patched using Kubernetes’ [kustomize](https://kustomize.io/). An example of a remote custom build is: + +``` +kustomize build github.com/kong/kubernetes-ingress-controller/deploy/manifests/base +``` + +kustomizations are available in Kong’s [repository](https://github.com/Kong/kubernetes-ingress-controller/tree/master/deploy/manifests) for different types of deployments. + + +## Using a managed Kubernetes offering +If you are using a cloud-provider to install Kong on a managed Kubernetes offering, such as Google Kubernetes Engine (GKE), Amazon EKS (EKS), Azure Kubernetes Service (AKS), and so on, ensure that you have set up your Kubernetes cluster on the cloud-provider and have `kubectl` configured on your workstation. + +Once you have a Kubernetes cluster and kubectl configured, installation for any cloud-provider uses one of the above methods ([YAML manifests](#yaml-manifests), [Helm Chart](#helm-chart), or [Kustomize](#kustomize)) to install Kong. + +Each cloud-provider has some minor variations in how they allow configuring specific resources like Load-balancers, volumes, etc. We recommend following their documentation to adjust these settings. + + +## Using a database for Kong for Kubernetes +If you are using a database, we recommend running Kong in the in-memory mode (also known as DB-less) inside Kubernetes as all of the configuration is stored in the Kubernetes control-plane. This setup simplifies Kong’s operations, so no need to worry about Database provisioning, backup, availability, security, etc. +If you decide to use a database, we recommend that you run the database outside of Kubernetes. You can use a service like Amazon’s RDS or a similar managed Postgres service from your cloud-provider to automate database operations. + +We do not recommend using Kong with Cassandra on Kubernetes deployments, as the features covered by Kong’s use of Cassandra are handled by other means in Kubernetes. + +## Next steps… +See [Using Kong for Kubernetes](/{{page.kong_version}}/kong-for-kubernetes/using-kong-for-kubernetes) for information about Concepts, How-to guides, and Reference guides. diff --git a/app/2.2.x/kong-for-kubernetes/using-kong-for-kubernetes.md b/app/2.2.x/kong-for-kubernetes/using-kong-for-kubernetes.md new file mode 100644 index 000000000000..6211be626369 --- /dev/null +++ b/app/2.2.x/kong-for-kubernetes/using-kong-for-kubernetes.md @@ -0,0 +1,74 @@ +--- +title: Using Kong for Kubernetes +toc: false +--- + +For information about using Kong for Kubernetes, see the documentation listed below that is available on Github at https://github.com/Kong/kubernetes-ingress-controller/tree/main/docs. + + +**Topics include:** +- [Concepts](#concepts) +- [Guides and Tutorials](#guides-and-tutorials) +- [Configuration Reference](#configuration-reference) +- [FAQs](#faqs) +- [Troubleshooting](#troubleshooting) +- [Contribute to the Community](#contribute-to-the-community) + + +### Concepts +Kong for Kubernetes concepts include: +- [Architecture](#architecture) +- [Custom Resources](#custom-resources) +- [Deployment Methods](#deployment-methods) +- [High-availability and Scaling](#high-availability-and-scaling) +- [Security](#security) + +#### Architecture +The [design](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/concepts/design.md) document explains how Kong Ingress Controller works inside a Kubernetes cluster and configures Kong to proxy traffic as per rules defined in the Ingress resources. + +#### Custom Resources +The Ingress resource in Kubernetes is a fairly narrow and ambiguous API, and does not offer resources to describe the specifics of proxying. To overcome this limitation, the KongIngress Custom resource is used as an "extension" to the existing Ingress API. + +A few custom resources are bundled with Kong Ingress Controller to configure settings that are specific to Kong and provide fine-grained control over the proxying behavior. + +See [custom resources](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/concepts/custom-resources.md) concept document for more details. + +#### Deployment Methods +Kong Ingress Controller can be deployed in a variety of deployment patterns. See the [deployment](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/concepts/deployment.md) documentation, which explains all of the components involved and different ways of deploying them based on the use-case. + +#### High-availability and Scaling +The Kong Ingress Controller is designed to scale with your traffic and infrastructure. See [High-availability and Scaling](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/concepts/ha-and-scaling.md) to understand failure scenarios, recovery methods, as well as scaling considerations. + +#### Security +See the [Security](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/concepts/security.md) document to understand the default security settings and how to further secure the Ingress Controller. + + + +### Guides and Tutorials +Browse through [guides](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/guides) to get started or understand how to configure a specific setting with Kong Ingress Controller. + +### Configuration Reference + +The configurations in the Kong Ingress Controller can be customized using Custom Resources and annotations. See the following documents detailing this process: + +- [Custom Resource Definitions](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/references/custom-resources.md) +- [Annotations](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/references/annotations.md) +- [CLI arguments](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/references/cli-arguments.md) + + + +### FAQs +[FAQs](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/faq.md) are available to help find answers to quickly resolve common problems. Feel free to open Pull Requests to contribute to the list. + + + +### Troubleshooting +See the [deployment guide](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/deployment) for a detailed understanding of how Kong Ingress Controller is designed and deployed along alongside Kong. + +Other resources include: +- [FAQs](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/faq.md) +- The [Troubleshooting guide](https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/troubleshooting.md) can help resolve some issues. + + +### Contribute to the Community +For a place to discuss and share Kong knowledge with the community, visit [Kong Nation](https://discuss.konghq.com/c/kubernetes). diff --git a/app/2.2.x/kong-security-update-process.md b/app/2.2.x/kong-security-update-process.md new file mode 100644 index 000000000000..2071f929beea --- /dev/null +++ b/app/2.2.x/kong-security-update-process.md @@ -0,0 +1,21 @@ +--- +title: Kong Security Update Process +layout: docs-v2 +--- + +## Reporting a Vulnerability + +If you have found a vulnerability or a potential vulnerability in the Kong gateway or other Kong software, or know of a publicly disclosed security vulnerability, please immediately let us know by emailing [security@konghq.com](mailto:security@konghq.com). We'll send a confirmation email to acknowledge your report, and we'll send an additional email when we've identified the issue positively or negatively. + +Once a report is received, we will investigate the vulnerability and assign it a [CVSS](https://www.first.org/cvss/) score which will determine the timeline for the development of an appropriate fix. + +While the fix development is underway, we ask that you do not share or publicize an unresolved vulnerability with third parties. If you responsibly submitted a vulnerability report, we will do our best to acknowledge your report in a timely fashion and notify you of the estimated timeline for a fix. + + +## Fix Development Process + +If a discovered vulnerability with a CVSS score above 4.0 (medium severity or higher) affects the latest major release of the Kong gateway or other Kong software, then we will work to develop a fix in the most timely fashion. The work and communication around the fix will happen in private channels, and a delivery estimate will be given to the vulnerability reporter. Once the fix is developed and verified, a new patch version will be released by Kong for each supported Kong Enterprise release and for the current release of the open source gateway. We will disclose the vulnerability as appropriate. + +Discovered vulnerabilities with a CVSS score below 4.0 (low severity) will follow the same fix development and release process but with a less urgent timeline. + +Vulnerabilities affecting upstream projects (e.g. NGINX, OpenResty, OpenSSL...) will receive fixes as per the upstream project's disclosure timeline. diff --git a/app/2.2.x/loadbalancing.md b/app/2.2.x/loadbalancing.md new file mode 100644 index 000000000000..1abf9075912a --- /dev/null +++ b/app/2.2.x/loadbalancing.md @@ -0,0 +1,385 @@ +--- +title: Loadbalancing reference +--- + +## Introduction + +Kong provides multiple ways of load balancing requests to multiple backend +services: a straightforward DNS-based method, and a more dynamic ring-balancer +that also allows for service registry without needing a DNS server. + +## DNS-based loadbalancing + +When using DNS-based load balancing, the registration of the backend services +is done outside of Kong, and Kong only receives updates from the DNS server. + +Every Service that has been defined with a `host` containing a hostname +(instead of an IP address) will automatically use DNS-based load balancing +if the name resolves to multiple IP addresses, provided the hostname does not +resolve to an `upstream` name or a name in your DNS hostsfile. + +The DNS record `ttl` setting (time to live) determines how often the information +is refreshed. When using a `ttl` of 0, every request will be resolved using its +own DNS query. Obviously this will have a performance penalty, but the latency of +updates/changes will be very low. + +[Back to top](#introduction) + +### A records + +An A record contains one or more IP addresses. Hence, when a hostname +resolves to an A record, each backend service must have its own IP address. + +Because there is no `weight` information, all entries will be treated as equally +weighted in the load balancer, and the balancer will do a straight forward +round-robin. + +[Back to top](#introduction) + +### SRV records + +An SRV record contains weight and port information for all of its IP addresses. +A backend service can be identified by a unique combination of IP address +and port number. Hence, a single IP address can host multiple instances of the +same service on different ports. + +Because the `weight` information is available, each entry will get its own +weight in the load balancer and it will perform a weighted round-robin. + +Similarly, any given port information will be overridden by the port information from +the DNS server. If a Service has attributes `host=myhost.com` and `port=123`, +and `myhost.com` resolves to an SRV record with `127.0.0.1:456`, then the request +will be proxied to `http://127.0.0.1:456/somepath`, as port `123` will be +overridden by `456`. + +[Back to top](#introduction) + +### DNS priorities + +The DNS resolver will start resolving the following record types in order: + + 1. The last successful type previously resolved + 2. SRV record + 3. A record + 4. CNAME record + +This order is configurable through the [`dns_order` configuration property][dns-order-config]. + +[Back to top](#introduction) + +### DNS caveats + +- Whenever the DNS record is refreshed a list is generated to handle the +weighting properly. Try to keep the weights as multiples of each other to keep +the algorithm performant, e.g., 2 weights of 17 and 31 would result in a structure +with 527 entries, whereas weights 16 and 32 (or their smallest relative +counterparts 1 and 2) would result in a structure with merely 3 entries, +especially with a very small (or even 0) `ttl` value. + +- DNS is carried over UDP with a default limit of 512 Bytes. If there are many entries +to be returned, a DNS Server will respond with partial data and set a truncate flag, +indicating there are more entries unsent. +DNS clients, including Kong's, will then make a second request over TCP to retrieve the full +list of entries. + +- Some nameservers by default do not respond with the truncate flag, but trim the response +to be under 512 byte UDP size. + - Consul is an example. Consul, in its default configuration, returns up to the first +three entries only, and does not set the truncate flag to indicate there are remaining entries unsent. +Consul includes an option to enable the truncate flag. Please refer to [Consul documentation](https://www.consul.io/docs/agent/options.html#enable_truncate) +for more information. + +- If a deployed nameserver does not provide the truncate flag, the pool +of upstream instances might be loaded inconsistently. The Kong node is effectively +unaware of some of the instances, due to the limited information provided by the nameserver. +To mitigate this, use a different nameserver, use IP addresses instead of names, or make sure +you use enough Kong nodes to still keep all upstream services in use. + +- When the nameserver returns a `3 name error`, then that is a valid response +for Kong. If this is unexpected, first validate the correct name is being +queried for, and second check your nameserver configuration. + +- The initial pick of an IP address from a DNS record (A or SRV) is not +randomized. So when using records with a `ttl` of 0, the nameserver is +expected to randomize the record entries. + +[Back to top](#introduction) + +## Ring-balancer + +When using the ring-balancer, the adding and removing of backend services will +be handled by Kong, and no DNS updates will be necessary. Kong will act as the +service registry. Nodes can be added/deleted with a single HTTP request and +will instantly start/stop receiving traffic. + +Configuring the ring-balancer is done through the `upstream` and `target` +entities. + + - `target`: an IP address or hostname with a port number where a backend + service resides, eg. "192.168.100.12:80". Each target gets an additional + `weight` to indicate the relative load it gets. IP addresses can be + in both IPv4 and IPv6 format. + + - `upstream`: a 'virtual hostname' which can be used in a Route `host` + field, e.g., an upstream named `weather.v2.service` would get all requests + from a Service with `host=weather.v2.service`. + +[Back to top](#introduction) + +### Upstream + +Each upstream gets its own ring-balancer. Each `upstream` can have many +`target` entries attached to it, and requests proxied to the 'virtual hostname' +(which can be overwritten before proxying, using `upstream`'s property +`host_header`) will be load balanced over the targets. A ring-balancer has a +pre-defined number of slots, and based on the target weights the slots get +assigned to the targets of the upstream. + +Adding and removing targets can be done with a simple HTTP request on the +Admin API. This operation is relatively cheap. Changing the upstream +itself is more expensive as the balancer will need to be rebuilt when the +number of slots change for example. + +The only occurrence where the balancer will be rebuilt automatically is when +the target history is cleaned; other than that, it will only rebuild upon changes. + +Within the balancer there are the positions (from 1 to `slots`), +which are __randomly distributed__ on the ring. +The randomness is required to make invoking the ring-balancer cheap at +runtime. A simple round-robin over the wheel (the positions) will do to +provide a well distributed weighted round-robin over the `targets`, whilst +also having cheap operations when inserting/deleting targets. + +The number of slots to use per target should (at least) be around 100 to make +sure the slots are properly distributed. Eg. for an expected maximum of 8 +targets, the `upstream` should be defined with at least `slots=800`, even if +the initial setup only features 2 targets. + +The tradeoff here is that the higher the number of slots, the better the random +distribution, but the more expensive the changes are (add/removing targets) + +Detailed information on adding and manipulating +upstreams is available in the `upstream` section of the +[Admin API reference][upstream-object-reference]. + +[Back to top](#introduction) + +### Target + +A target is an ip address/hostname with a port that identifies an instance of +a backend service. Each upstream can have many targets. +Detailed information on adding and manipulating targets is available in the +`target` section of the [Admin API reference][target-object-reference]. + +The targets will be automatically cleaned when there are 10x more inactive +entries than active ones. Cleaning will involve rebuilding the balancer, and +hence is more expensive than just adding a target entry. + +A `target` can also have a hostname instead of an IP address. In that case +the name will be resolved and all entries found will individually be added to +the ring balancer, e.g., adding `api.host.com:123` with `weight=100`. The +name 'api.host.com' resolves to an A record with 2 IP addresses. Then both +ip addresses will be added as target, each getting `weight=100` and port 123. +__NOTE__: the weight is used for the individual entries, not for the whole! + +Would it resolve to an SRV record, then also the `port` and `weight` fields +from the DNS record would be picked up, and would overrule the given port `123` +and `weight=100`. + +The balancer will honor the DNS record's `ttl` setting and requery and update +the balancer when it expires. + +__Exception__: When a DNS record has `ttl=0`, the hostname will be added +as a single target, with the specified weight. Upon every proxied request +to this target it will query the nameserver again. + +[Back to top](#introduction) + +### Balancing algorithms + +The ring-balancer supports the following load balancing algorithms: `round-robin`, +`consistent-hashing`, and `least-connections`. By default, a ring-balancer +uses the `round-robin` algorithm, which provides a well-distributed weighted +round-robin over the targets. + +When using the `consistent-hashing` algorithm, the input for the hash can be either +`none`, `consumer`, `ip`, `header`, or `cookie`. When set to `none`, the +`round-robin` scheme will be used, and hashing will be disabled. The `consistent-hashing` +algorithm supports a primary and a fallback hashing attribute; in case the primary +fails (e.g., if the primary is set to `consumer`, but no Consumer is authenticated), +the fallback attribute is used. + +Supported hashing attributes are: + +- `none`: Do not use `consistent-hashing`; use `round-robin` instead (default). +- `consumer`: Use the Consumer ID as the hash input. If no Consumer ID is available, + it will fall back on the Credential ID (for example, in case of an external authentication mechanism like LDAP). +- `ip`: Use the originating IP address as the hash input. Review the configuration + settings for [determining the real IP][real-ip-config] when using this. +- `header`: Use a specified header as the hash input. The header name is + specified in either `hash_on_header` or `hash_fallback_header`, depending on whether + `header` is a primary or fallback attribute, respectively. +- `cookie`: Use a specified cookie with a specified path as the hash input. + The cookie name is specified in the `hash_on_cookie` field and the path is + specified in the `hash_on_cookie_path` field. If the specified cookie is not + present in the request, it will be set by the response. Hence, the `hash_fallback` + setting is invalid if `cookie` is the primary hashing mechanism. + +The `consistent-hashing` algorithm is based on _Consistent Hashing_ (or the +_Ketama Principle_), which ensures that when the balancer gets modified by +a change in its targets (adding, removing, failing, or changing weights), only +the minimum number of hashing losses occur. This maximizes upstream cache hits. + +The ring-balancer also supports the `least-connections` algorithm, which selects +the target with the lowest number of connections, weighted by the Target's +`weight` attribute. + +For more information on the exact settings see the `upstream` section of the +[Admin API reference][upstream-object-reference]. + +[Back to top](#introduction) + +### Balancing caveats + +The ring-balancer is designed to work both with a single node as well as in a cluster. +For the weighted-round-robin algorithm there isn't much difference, but when using +the hash based algorithm it is important that all nodes build the exact same +ring-balancer to make sure they all work identical. To do this the balancer +must be build in a deterministic way. + +- Do not use hostnames in the balancer as the +balancers might/will slowly diverge because the DNS ttl has only second precision +and renewal is determined by when a name is actually requested. On top of this is +the issue with some nameservers not returning all entries, which exacerbates +this problem. So when using the hashing approach in a Kong cluster, add `target` +entities only by their IP address, and never by name. + +- When picking your hash input make sure the input has enough variance to get +to a well distributed hash. Hashes will be calculated using the CRC-32 digest. +So for example, if your system has thousands of users, but only a few consumers, defined +per platform (eg. 3 consumers: Web, iOS and Android) then picking the `consumer` +hash input will not suffice, using the remote IP address by setting the hash to +`ip` would provide more variance in the input and hence a better distribution +in the hash output. However, if many clients will be behind the same NAT gateway (e.g. in +call center), `cookie` will provide a better distribution than `ip`. + +[Back to top](#introduction) + +# Blue-Green Deployments + +Using the ring-balancer a [blue-green deployment][blue-green-canary] can be easily orchestrated for +a Service. Switching target infrastructure only requires a `PATCH` request on a +Service, to change its `host` value. + +Set up the "Blue" environment, running version 1 of the address service: + +```bash +# create an upstream +$ curl -X POST http://kong:8001/upstreams \ + --data "name=address.v1.service" + +# add two targets to the upstream +$ curl -X POST http://kong:8001/upstreams/address.v1.service/targets \ + --data "target=192.168.34.15:80" + --data "weight=100" +$ curl -X POST http://kong:8001/upstreams/address.v1.service/targets \ + --data "target=192.168.34.16:80" + --data "weight=50" + +# create a Service targeting the Blue upstream +$ curl -X POST http://kong:8001/services/ \ + --data "name=address-service" \ + --data "host=address.v1.service" \ + --data "path=/address" + +# finally, add a Route as an entry-point into the Service +$ curl -X POST http://kong:8001/services/address-service/routes/ \ + --data "hosts[]=address.mydomain.com" +``` + +Requests with host header set to `address.mydomain.com` will now be proxied +by Kong to the two defined targets; 2/3 of the requests will go to +`http://192.168.34.15:80/address` (`weight=100`), and 1/3 will go to +`http://192.168.34.16:80/address` (`weight=50`). + +Before deploying version 2 of the address service, set up the "Green" +environment: + +```bash +# create a new Green upstream for address service v2 +$ curl -X POST http://kong:8001/upstreams \ + --data "name=address.v2.service" + +# add targets to the upstream +$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.17:80" + --data "weight=100" +$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.18:80" + --data "weight=100" +``` + +To activate the Blue/Green switch, we now only need to update the Service: + +```bash +# Switch the Service from Blue to Green upstream, v1 -> v2 +$ curl -X PATCH http://kong:8001/services/address-service \ + --data "host=address.v2.service" +``` + +Incoming requests with host header set to `address.mydomain.com` will now be +proxied by Kong to the new targets; 1/2 of the requests will go to +`http://192.168.34.17:80/address` (`weight=100`), and the other 1/2 will go to +`http://192.168.34.18:80/address` (`weight=100`). + +As always, the changes through the Kong Admin API are dynamic and will take +effect immediately. No reload or restart is required, and no in progress +requests will be dropped. + +[Back to top](#introduction) + +# Canary Releases + +Using the ring-balancer, target weights can be adjusted granularly, allowing +for a smooth, controlled [canary release][blue-green-canary]. + +Using a very simple 2 target example: + +```bash +# first target at 1000 +$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.17:80" + --data "weight=1000" + +# second target at 0 +$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.18:80" + --data "weight=0" +``` + +By repeating the requests, but altering the weights each time, traffic will +slowly be routed towards the other target. For example, set it at 10%: + +```bash +# first target at 900 +$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.17:80" + --data "weight=900" + +# second target at 100 +$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ + --data "target=192.168.34.18:80" + --data "weight=100" +``` + +The changes through the Kong Admin API are dynamic and will take +effect immediately. No reload or restart is required, and no in progress +requests will be dropped. + +[Back to top](#introduction) + +[upstream-object-reference]: /{{page.kong_version}}/admin-api#upstream-object +[target-object-reference]: /{{page.kong_version}}/admin-api#target-object +[dns-order-config]: /{{page.kong_version}}/configuration/#dns_order +[real-ip-config]: /{{page.kong_version}}/configuration/#real_ip_header +[blue-green-canary]: http://blog.christianposta.com/deploy/blue-green-deployments-a-b-testing-and-canary-releases/ diff --git a/app/2.2.x/logging.md b/app/2.2.x/logging.md new file mode 100644 index 000000000000..086ff453df78 --- /dev/null +++ b/app/2.2.x/logging.md @@ -0,0 +1,145 @@ +--- +title: Logging Reference +toc: false +--- + +## Log Levels + +Log levels are set in [Kong's configuration](/{{page.kong_version}}/configuration/#log_level). Following are the log levels in increasing order of their severity, `debug`, `info`, +`notice`, `warn`, `error` and `crit`. + +- *`debug`:* It provides debug information about the plugin's runloop and each individual plugin or other components. Only to be used during debugging since it is too chatty. +- *`info`/`notice`:* Kong does not make a big difference between both these levels. Provides information about normal behavior most of which can be ignored. +- *`warn`:* To log any abnormal behavior that doesn't result in dropped transactions but requires further investigation, `warn` level should be used. +- *`error`:* Used for logging errors that result in a request being dropped (for example getting an HTTP 500 error). The rate of such logs need to be monitored. +- *`crit`:* This level is used when Kong is working under critical conditions and not working properly thereby affecting several clients. Nginx also provides `alert` and `emerg` levels but currently Kong doesn't make use of these levels making `crit` the highest severity log level. + +By default `notice` is the log level that used and also recommended. However if the logs turn out to be too chatty they can be bumped up to a higher level like `warn`. + +## Removing Certain Elements From Your Kong Logs + +With new regulations surrounding protecting private data like GDPR, there is a chance you may need to change your logging habits. If you use Kong as your API Gateway, this can be done in a single location to take effect on all of your Services. This guide will walk you through one approach to accomplishing this, but there are always different approaches for different needs. Please note, these changes will effect the output of the NGINX access logs. This will not have any effect on Kong's logging plugins. + +For this example, let’s say you want to remove any instances of an email address from your kong logs. The emails addresses may come through in different ways, for example something like `/servicename/v2/verify/alice@example.com` or `/v3/verify?alice@example.com`. In order to keep these from being added to the logs, we will need to use a custom NGINX template. + +To start using a custom NGINX template, first get a copy of our template. This can be found [https://docs.konghq.com/latest/configuration/#custom-nginx-templates--embedding-kong](https://docs.konghq.com/latest/configuration/#custom-nginx-templates--embedding-kong) or copied from below + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{NGINX_WORKER_PROCESSES}}; # can be set by kong.conf +daemon ${{NGINX_DAEMON}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log logs/error.log ${{LOG_LEVEL}}; # can be set by kong.conf + +events { + use epoll; # custom setting + multi_accept on; +} + +http { + # include default Kong Nginx config + include 'nginx-kong.conf'; + + # custom server + server { + listen 8888; + server_name custom_server; + + location / { + ... # etc + } + } +} +``` + +In order to control what is placed in the logs, we will be using the NGINX map module in our template. For more detailed information abut using the map directive, please see [this guide](http://nginx.org/en/docs/http/ngx_http_map_module.html). This will create a new variable whose value depends on values of one or more of the source variables specified in the first parameter. The format is: + +``` + +map $paramater_to_look_at $variable_name { + pattern_to_look_for 0; + second_pattern_to_look_for 0; + + default 1; +} +``` + +For this example, we will be mapping a new variable called `keeplog` which is dependent on certain values appearing in the `$request_uri`. We will be placing our map directive right at the start of the http block, this must be before `include 'nginx-kong.conf';`. So, for our example, we will add something along the lines of: + +``` +map $request_uri $keeplog { + ~.+\@.+\..+ 0; + ~/servicename/v2/verify 0; + ~/v3/verify 0; + + default 1; +} +``` + +You’ll probably notice that each of those lines start with a tilde. This is what tells NGINX to use RegEx when evaluating the line. We have three things to look for in this example: +- The first line uses regex to look for any email address in the x@y.z format +- The second line looks for any part of the URI which is /servicename/v2/verify +- The third line looks at any part of the URI which contains /v3/verify + +Because all of those have a value of something other than 0, if a request has one of those elements, it will not be added to the log. + +Now, we need to set the log format for what we will keep in the logs. We will use the `log_format` module and assign our new logs a name of show_everything. The contents of the log can be customized for you needs, but for this example, I will simply change everything back to the Kong standards. To see the full list of options you can use, please refer to [this guide](https://nginx.org/en/docs/http/ngx_http_core_module.html#variables). + +``` +log_format show_everything '$remote_addr - $remote_user [$time_local] ' + '$request_uri $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; +``` + +Now, our custom NGINX template is all ready to be used. If you have been following along, your file should now be look like this: + +``` +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{NGINX_WORKER_PROCESSES}}; # can be set by kong.conf +daemon ${{NGINX_DAEMON}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log stderr ${{LOG_LEVEL}}; # can be set by kong.conf + + + +events { + use epoll; # custom setting + multi_accept on; +} + +http { + + + map $request_uri $keeplog { + ~.+\@.+\..+ 0; + ~/v1/invitation/ 0; + ~/reset/v1/customer/password/token 0; + ~/v2/verify 0; + + default 1; + } + log_format show_everything '$remote_addr - $remote_user [$time_local] ' + '$request_uri $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; + + include 'nginx-kong.conf'; +} +``` + +The last thing we need to do is tell Kong to use the newly created log, `show_everything`. To do this, we will be altering the Kong variable `proxy_access_log`. Either by opening and editing `etc/kong/kong.conf` or by using an environmental variable `KONG_PROXY_ACCESS_LOG=` you will want to mend the default location to show + +``` +proxy_access_log=logs/access.log show_everything if=$keeplog +``` + +The final step in the process to make all the changes take effect is to restart kong. you can use the `kong restart` command to do so. + +Now, any requests made with an email address in it will no longer be logged. Of course, we can use this logic to remove anything we want from the logs on a conditional manner. diff --git a/app/2.2.x/network.md b/app/2.2.x/network.md new file mode 100644 index 000000000000..982ed602ac59 --- /dev/null +++ b/app/2.2.x/network.md @@ -0,0 +1,70 @@ +--- +title: Network & Firewall +--- + +## Introduction + +In this section you will find a summary about the recommended network and firewall settings for Kong. + +## Ports + +Kong uses multiple connections for different purposes. + +* proxy +* admin api + +### Proxy + +The proxy ports is where Kong receives its incoming traffic. There are two ports with the following defaults: + +* `8000` for proxying HTTP traffic, and +* `8443` for proxying HTTPS traffic + +See [proxy_listen] for more details on HTTP/HTTPS proxy listen options. For production environment it is common +to change HTTP and HTTPS listen ports to `80` and `443`. + +Kong can also proxy TCP/TLS and UDP streams. The stream proxying is disabled by default. See [stream_listen] for +additional details on stream proxy listen options, and how to enable it (if you plan to proxy anything other than +HTTP/HTTPS traffic). + +In general the proxy ports are the **only ports** that should be made available to your clients. + +### Admin API + +This is the port where Kong exposes its management API. Hence in production this port should be firewalled to protect +it from unauthorized access. + +* `8001` provides Kong's **Admin API** that you can use to operate Kong with HTTP. See [admin_listen]. +* `8444` provides the same Kong **Admin API** but using HTTPS. See [admin_listen] and the `ssl` suffix. + +## Firewall + +Below are the recommended firewall settings: + +* The upstream Services behind Kong will be available via the [proxy_listen] interface/port values. + Configure these values according to the access level you wish to grant to the upstream Services. +* If you are binding the Admin API to a public-facing interface (via [admin_listen]), then **protect** it to only + allow trusted clients to access the Admin API. See also [Securing the Admin API][secure_admin_api]. +* Your proxy will need have rules added for any HTTP/HTTPS and TCP/TLS stream listeners that you configure. + For example, if you want Kong to manage traffic on port `4242`, your firewall will need to allow traffic + on said port. + +#### Transparent Proxying + +It is worth mentioning that the `transparent` listen option may be applied to [proxy_listen] +and [stream_listen] configuration. With packet filtering such as `iptables` (Linux) or `pf` (macOS/BSDs) +or with hardware routers/switches, you can specify pre-routing or redirection rules for TCP packets that +allow you to mangle the original destination address and port. For example a HTTP request with a destination +address of `10.0.0.1`, and a destination port of `80` can be redirected to `127.0.0.1` at port `8000`. +To make this work, you need (with Linux) to add the `transparent` listen option to Kong proxy, +`proxy_listen=8000 transparent`. This allows Kong to see the original destination for the request +(`10.0.0.1:80`) even when Kong didn't actually listen to it directly. With this information, +Kong can route the request correctly. The `transparent` listen option should only be used with Linux. +macOS/BSDs allow transparent proxying without `transparent` listen option. With Linux you may also need +to start Kong as a `root` user or set the needed capabilities for the executable. + + +[proxy_listen]: /{{page.kong_version}}/configuration/#proxy_listen +[stream_listen]: /{{page.kong_version}}/configuration/#stream_listen +[admin_listen]: /{{page.kong_version}}/configuration/#admin_listen +[secure_admin_api]: /{{page.kong_version}}/secure-admin-api diff --git a/app/2.2.x/pdk/index.md b/app/2.2.x/pdk/index.md new file mode 100644 index 000000000000..ce4bb3a6a81f --- /dev/null +++ b/app/2.2.x/pdk/index.md @@ -0,0 +1,183 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: PDK +pdk: true +toc: true +--- + +## Plugin Development Kit + +The Plugin Development Kit (or "PDK") is set of Lua functions and variables + that can be used by plugins to implement their own logic. The PDK is a + [Semantically Versioned](https://semver.org/) component, originally + released in Kong 0.14.0. The PDK will be guaranteed to be forward-compatible + from its 1.0.0 release and on. + + As of this release, the PDK has not yet reached 1.0.0, but plugin authors + can already depend on it for a safe and reliable way of interacting with the + request, response, or the core components. + + The Plugin Development Kit is accessible from the `kong` global variable, + and various functionalities are namespaced under this table, such as + `kong.request`, `kong.log`, etc... + + + + +### kong.version + +A human-readable string containing the version number of the currently + running node. + +**Usage** + +``` lua +print(kong.version) -- "2.0.0" +``` + +[Back to top](#plugin-development-kit) + + +### kong.version_num + +An integral number representing the version number of the currently running + node, useful for comparison and feature-existence checks. + +**Usage** + +``` lua +if kong.version_num < 13000 then -- 000.130.00 -> 0.13.0 + -- no support for Routes & Services +end +``` + +[Back to top](#plugin-development-kit) + + +### kong.pdk_major_version + +A number representing the major version of the current PDK (e.g. + `1`). Useful for feature-existence checks or backwards-compatible behavior + as users of the PDK. + + +**Usage** + +``` lua +if kong.pdk_version_num < 2 then + -- PDK is below version 2 +end +``` + +[Back to top](#plugin-development-kit) + + +### kong.pdk_version + +A human-readable string containing the version number of the current PDK. + +**Usage** + +``` lua +print(kong.pdk_version) -- "1.0.0" +``` + +[Back to top](#plugin-development-kit) + + +### kong.configuration + +A read-only table containing the configuration of the current Kong node, + based on the configuration file and environment variables. + + See [kong.conf.default](https://github.com/Kong/kong/blob/master/kong.conf.default) + for details. + + Comma-separated lists in that file get promoted to arrays of strings in this + table. + + +**Usage** + +``` lua +print(kong.configuration.prefix) -- "/usr/local/kong" +-- this table is read-only; the following throws an error: +kong.configuration.prefix = "foo" +``` + +[Back to top](#plugin-development-kit) + + + + +### kong.db + +Instance of Kong's DAO (the `kong.db` module). Contains accessor objects + to various entities. + + A more thorough documentation of this DAO and new schema definitions is to + be made available in the future. + + +**Usage** + +``` lua +kong.db.services:insert() +kong.db.routes:select() +``` + +[Back to top](#plugin-development-kit) + + +### kong.dns + +Instance of Kong's DNS resolver, a client object from the + [lua-resty-dns-client](https://github.com/kong/lua-resty-dns-client) module. + + **Note:** usage of this module is currently reserved to the core or to + advanced users. + + +[Back to top](#plugin-development-kit) + + +### kong.worker_events + +Instance of Kong's IPC module for inter-workers communication from the + [lua-resty-worker-events](https://github.com/Kong/lua-resty-worker-events) + module. + + **Note:** usage of this module is currently reserved to the core or to + advanced users. + + +[Back to top](#plugin-development-kit) + + +### kong.cluster_events + +Instance of Kong's cluster events module for inter-nodes communication. + + **Note:** usage of this module is currently reserved to the core or to + advanced users. + + +[Back to top](#plugin-development-kit) + + +### kong.cache + +Instance of Kong's database caching object, from the `kong.cache` module. + + **Note:** usage of this module is currently reserved to the core or to + advanced users. + + +[Back to top](#plugin-development-kit) + + diff --git a/app/2.2.x/pdk/kong.client.md b/app/2.2.x/pdk/kong.client.md new file mode 100644 index 000000000000..37436ec33241 --- /dev/null +++ b/app/2.2.x/pdk/kong.client.md @@ -0,0 +1,301 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.client +pdk: true +toc: true +--- + +## kong.client + +Client information module + A set of functions to retrieve information about the client connecting to + Kong in the context of a given request. + + See also: + [nginx.org/en/docs/http/ngx_http_realip_module.html](http://nginx.org/en/docs/http/ngx_http_realip_module.html) + + + +### kong.client.get_ip() + +Returns the remote address of the client making the request. This will + **always** return the address of the client directly connecting to Kong. + That is, in cases when a load balancer is in front of Kong, this function + will return the load balancer's address, and **not** that of the + downstream client. + + +**Phases** + +* certificate, rewrite, access, header_filter, body_filter, log + +**Returns** + +* `string` ip The remote address of the client making the request + + +**Usage** + +``` lua +-- Given a client with IP 127.0.0.1 making connection through +-- a load balancer with IP 10.0.0.1 to Kong answering the request for +-- https://example.com:1234/v1/movies +kong.client.get_ip() -- "10.0.0.1" +``` + +[Back to top](#kongclient) + + +### kong.client.get_forwarded_ip() + +Returns the remote address of the client making the request. Unlike + `kong.client.get_ip`, this function will consider forwarded addresses in + cases when a load balancer is in front of Kong. Whether this function + returns a forwarded address or not depends on several Kong configuration + parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + + +**Phases** + +* certificate, rewrite, access, header_filter, body_filter, log + +**Returns** + +* `string` ip The remote address of the client making the request, + considering forwarded addresses + + + +**Usage** + +``` lua +-- Given a client with IP 127.0.0.1 making connection through +-- a load balancer with IP 10.0.0.1 to Kong answering the request for +-- https://username:password@example.com:1234/v1/movies + +kong.request.get_forwarded_ip() -- "127.0.0.1" + +-- Note: assuming that 10.0.0.1 is one of the trusted IPs, and that +-- the load balancer adds the right headers matching with the configuration +-- of `real_ip_header`, e.g. `proxy_protocol`. +``` + +[Back to top](#kongclient) + + +### kong.client.get_port() + +Returns the remote port of the client making the request. This will + **always** return the port of the client directly connecting to Kong. That + is, in cases when a load balancer is in front of Kong, this function will + return load balancer's port, and **not** that of the downstream client. + +**Phases** + +* certificate, rewrite, access, header_filter, body_filter, log + +**Returns** + +* `number` The remote client port + + +**Usage** + +``` lua +-- [client]:40000 <-> 80:[balancer]:30000 <-> 80:[kong]:20000 <-> 80:[service] +kong.client.get_port() -- 30000 +``` + +[Back to top](#kongclient) + + +### kong.client.get_forwarded_port() + +Returns the remote port of the client making the request. Unlike + `kong.client.get_port`, this function will consider forwarded ports in cases + when a load balancer is in front of Kong. Whether this function returns a + forwarded port or not depends on several Kong configuration parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + +**Phases** + +* certificate, rewrite, access, header_filter, body_filter, log + +**Returns** + +* `number` The remote client port, considering forwarded ports + + +**Usage** + +``` lua +-- [client]:40000 <-> 80:[balancer]:30000 <-> 80:[kong]:20000 <-> 80:[service] +kong.client.get_forwarded_port() -- 40000 + +-- Note: assuming that [balancer] is one of the trusted IPs, and that +-- the load balancer adds the right headers matching with the configuration +-- of `real_ip_header`, e.g. `proxy_protocol`. +``` + +[Back to top](#kongclient) + + +### kong.client.get_credential() + +Returns the credentials of the currently authenticated consumer. + If not set yet, it returns `nil`. + +**Phases** + +* access, header_filter, body_filter, log + +**Returns** + +* the authenticated credential + + +**Usage** + +``` lua +local credential = kong.client.get_credential() +if credential then + consumer_id = credential.consumer_id +else + -- request not authenticated yet +end +``` + +[Back to top](#kongclient) + + +### kong.client.load_consumer(consumer_id, search_by_username) + +Returns the consumer from the datastore (or cache). + Will look up the consumer by id, and optionally will do a second search by name. + +**Phases** + +* access, header_filter, body_filter, log + +**Parameters** + +* **consumer_id** (string): The consumer id to look up. +* **search_by_username** ([opt]): boolean. If truthy, + then if the consumer was not found by id, + then a second search by username will be performed + +**Returns** + +1. `table|nil` consumer entity or nil + +1. `nil|err` nil if success, or error message if failure + + +**Usage** + +``` lua +local consumer_id = "john_doe" +local consumer = kong.client.load_consumer(consumer_id, true) +``` + +[Back to top](#kongclient) + + +### kong.client.get_consumer() + +Returns the `consumer` entity of the currently authenticated consumer. + If not set yet, it returns `nil`. + +**Phases** + +* access, header_filter, body_filter, log + +**Returns** + +* `table` the authenticated consumer entity + + +**Usage** + +``` lua +local consumer = kong.client.get_consumer() +if consumer then + consumer_id = consumer.id +else + -- request not authenticated yet, or a credential + -- without a consumer (external auth) +end +``` + +[Back to top](#kongclient) + + +### kong.client.authenticate(consumer, credential) + +Sets the authenticated consumer and/or credential for the current request. + While both `consumer` and `credential` can be `nil`, it is required + that at least one of them exists. Otherwise this function will throw an + error. + +**Phases** + +* access + +**Parameters** + +* **consumer** (table|nil): The consumer to set. Note: if no + value is provided, then any existing value will be cleared! +* **credential** (table|nil): The credential to set. Note: if + no value is provided, then any existing value will be cleared! + +**Usage** + +``` lua +-- assuming `credential` and `consumer` have been set by some authentication code +kong.client.authenticate(consumer, credentials) +``` + +[Back to top](#kongclient) + + +### kong.client.get_protocol(allow_terminated) + +Returns the protocol matched by the current route (`"http"`, `"https"`, `"tcp"` or + `"tls"`), or `nil`, if no route has been matched, which can happen when dealing with + erroneous requests. + +**Phases** + +* access, header_filter, body_filter, log + +**Parameters** + +* **allow_terminated** ([opt]): boolean. If set, the `X-Forwarded-Proto` header will be checked when checking for https + +**Returns** + +1. `string|nil` `"http"`, `"https"`, `"tcp"`, `"tls"` or `nil` + +1. `nil|err` nil if success, or error message if failure + + +**Usage** + +``` lua +kong.client.get_protocol() -- "http" +``` + +[Back to top](#kongclient) + diff --git a/app/2.2.x/pdk/kong.client.tls.md b/app/2.2.x/pdk/kong.client.tls.md new file mode 100644 index 000000000000..4515a4c55eff --- /dev/null +++ b/app/2.2.x/pdk/kong.client.tls.md @@ -0,0 +1,146 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.client.tls +pdk: true +toc: true +--- + +## kong.client.tls + +The client.tls module provides functions for interacting with TLS + connections from client. + + + +### kong.client.tls.request_client_certificate() + +Requests client to present its client-side certificate to initiate mutual + TLS authentication between server and client. + + This function only *requests*, but does not *require* the client to start + the mTLS process. Even if the client did not present a client certificate + the TLS handshake will still complete (obviously not being mTLS in that + case). Whether the client honored the request can be determined using + get_full_client_certificate_chain in later phases. + + +**Phases** + +* certificate + +**Returns** + +1. `true|nil` true if request was received, nil if request failed + +1. `nil|err` nil if success, or error message if failure + + +**Usage** + +``` lua +local res, err = kong.client.tls.request_client_certificate() +if not res then + -- do something with err +end +``` + +[Back to top](#kongclienttls) + + +### kong.client.tls.disable_session_reuse() + +Prevents the TLS session for the current connection from being reused + by disabling session ticket and session ID for the current TLS connection. + +**Phases** + +* certificate + +**Returns** + +1. `true|nil` true if success, nil if failed + +1. `nil|err` nil if success, or error message if failure + + +**Usage** + +``` lua +local res, err = kong.client.tls.disable_session_reuse() +if not res then + -- do something with err +end +``` + +[Back to top](#kongclienttls) + + +### kong.client.tls.get_full_client_certificate_chain() + +Returns the PEM encoded downstream client certificate chain with the + client certificate at the top and intermediate certificates + (if any) at the bottom. + +**Phases** + +* rewrite, access, balancer, header_filter, body_filter, log + +**Returns** + +1. `string|nil` PEM-encoded client certificate if mTLS handshake + was completed, nil if an error occurred or client did not present + its certificate + +1. `nil|err` nil if success, or error message if failure + + +**Usage** + +``` lua +local cert, err = kong.client.get_full_client_certificate_chain() +if err then + -- do something with err +end + +if not cert then + -- client did not complete mTLS +end + +-- do something with cert +``` + +[Back to top](#kongclienttls) + + +### kong.client.tls.set_client_verify() + +Overrides client verify result generated by the log serializer. + + By default, the `request.tls.client_verify` field inside the log + generated by Kong's log serializer is the same as the + [$ssl_client_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify) + Nginx variable. + + Only "SUCCESS", "NONE" or "FAILED:" are accepted values. + + This function does not return anything on success, and throws an Lua error + in case of failures. + + +**Phases** + +* rewrite, access, balancer + +**Usage** + +``` lua +kong.client.tls.set_client_verify("FAILED:unknown CA") +``` + +[Back to top](#kongclienttls) + diff --git a/app/2.2.x/pdk/kong.ctx.md b/app/2.2.x/pdk/kong.ctx.md new file mode 100644 index 000000000000..41f6403f04ba --- /dev/null +++ b/app/2.2.x/pdk/kong.ctx.md @@ -0,0 +1,113 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.ctx +pdk: true +toc: true +--- + +## kong.ctx + +Current request context data + + + +### kong.ctx.shared + +A table that has the lifetime of the current request and is shared between + all plugins. It can be used to share data between several plugins in a given + request. + + Since only relevant in the context of a request, this table cannot be + accessed from the top-level chunk of Lua modules. Instead, it can only be + accessed in request phases, which are represented by the `rewrite`, + `access`, `header_filter`, `body_filter`, `log`, and `preread` phases of + the plugin interfaces. Accessing this table in those functions (and their + callees) is fine. + + Values inserted in this table by a plugin will be visible by all other + plugins. One must use caution when interacting with its values, as a naming + conflict could result in the overwrite of data. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, preread + +**Usage** + +``` lua +-- Two plugins A and B, and if plugin A has a higher priority than B's +-- (it executes before B): + +-- plugin A handler.lua +function plugin_a_handler:access(conf) + kong.ctx.shared.foo = "hello world" + + kong.ctx.shared.tab = { + bar = "baz" + } +end + +-- plugin B handler.lua +function plugin_b_handler:access(conf) + kong.log(kong.ctx.shared.foo) -- "hello world" + kong.log(kong.ctx.shared.tab.bar) -- "baz" +end +``` + +[Back to top](#kongctx) + + +### kong.ctx.plugin + +A table that has the lifetime of the current request - Unlike + `kong.ctx.shared`, this table is **not** shared between plugins. + Instead, it is only visible for the current plugin _instance_. + That is, if several instances of the rate-limiting plugin + are configured (e.g. on different Services), each instance has its + own table, for every request. + + Because of its namespaced nature, this table is safer for a plugin to use + than `kong.ctx.shared` since it avoids potential naming conflicts, which + could lead to several plugins unknowingly overwriting each other's data. + + Since only relevant in the context of a request, this table cannot be + accessed from the top-level chunk of Lua modules. Instead, it can only be + accessed in request phases, which are represented by the `rewrite`, + `access`, `header_filter`, `body_filter`, `log`, and `preread` phases + of the plugin interfaces. Accessing this table in those functions (and + their callees) is fine. + + Values inserted in this table by a plugin will be visible in successful + phases of this plugin's instance only. For example, if a plugin wants to + save some value for post-processing during the `log` phase: + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, preread + +**Usage** + +``` lua +-- plugin handler.lua + +function plugin_handler:access(conf) + kong.ctx.plugin.val_1 = "hello" + kong.ctx.plugin.val_2 = "world" +end + +function plugin_handler:log(conf) + local value = kong.ctx.plugin.val_1 .. " " .. kong.ctx.plugin.val_2 + + kong.log(value) -- "hello world" +end +``` + +[Back to top](#kongctx) + diff --git a/app/2.2.x/pdk/kong.ip.md b/app/2.2.x/pdk/kong.ip.md new file mode 100644 index 000000000000..cb64b67080ab --- /dev/null +++ b/app/2.2.x/pdk/kong.ip.md @@ -0,0 +1,57 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.ip +pdk: true +toc: true +--- + +## kong.ip + +Trusted IPs module + + This module can be used to determine whether or not a given IP address is + in the range of trusted IP addresses defined by the `trusted_ips` configuration + property. + + Trusted IP addresses are those that are known to send correct replacement + addresses for clients (as per the chosen header field, e.g. X-Forwarded-*). + + See [docs.konghq.com/latest/configuration/#trusted_ips](https://docs.konghq.com/latest/configuration/#trusted_ips) + + + + +### kong.ip.is_trusted(address) + +Depending on the `trusted_ips` configuration property, + this function will return whether a given ip is trusted or not Both ipv4 and ipv6 are supported. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, body_filter, log + +**Parameters** + +* **address** (string): A string representing an IP address + +**Returns** + +* `boolean` `true` if the IP is trusted, `false` otherwise + + +**Usage** + +``` lua +if kong.ip.is_trusted("1.1.1.1") then + kong.log("The IP is trusted") +end +``` + +[Back to top](#kongip) + diff --git a/app/2.2.x/pdk/kong.log.md b/app/2.2.x/pdk/kong.log.md new file mode 100644 index 000000000000..db8ae247a65a --- /dev/null +++ b/app/2.2.x/pdk/kong.log.md @@ -0,0 +1,326 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.log +pdk: true +toc: true +--- + +## kong.log + +This namespace contains an instance of a "logging facility", which is a + table containing all of the methods described below. + + This instance is namespaced per plugin, and Kong will make sure that before + executing a plugin, it will swap this instance with a logging facility + dedicated to the plugin. This allows the logs to be prefixed with the + plugin's name for debugging purposes. + + + + +### kong.log(...) + +Write a log line to the location specified by the current Nginx + configuration block's `error_log` directive, with the `notice` level (similar + to `print()`). + + The Nginx `error_log` directive is set via the `log_level`, `proxy_error_log` + and `admin_error_log` Kong configuration properties. + + Arguments given to this function will be concatenated similarly to + `ngx.log()`, and the log line will report the Lua file and line number from + which it was invoked. Unlike `ngx.log()`, this function will prefix error + messages with `[kong]` instead of `[lua]`. + + Arguments given to this function can be of any type, but table arguments + will be converted to strings via `tostring` (thus potentially calling a + table's `__tostring` metamethod if set). This behavior differs from + `ngx.log()` (which only accepts table arguments if they define the + `__tostring` metamethod) with the intent to simplify its usage and be more + forgiving and intuitive. + + Produced log lines have the following format when logging is invoked from + within the core: + + ``` plain + [kong] %file_src:%line_src %message + ``` + + In comparison, log lines produced by plugins have the following format: + + ``` plain + [kong] %file_src:%line_src [%namespace] %message + ``` + + Where: + + * `%namespace`: is the configured namespace (the plugin name in this case). + * `%file_src`: is the file name from where the log was called from. + * `%line_src`: is the line number from where the log was called from. + * `%message`: is the message, made of concatenated arguments given by the caller. + + For example, the following call: + + ``` lua + kong.log("hello ", "world") + ``` + + would, within the core, produce a log line similar to: + + ``` plain + 2017/07/09 19:36:25 [notice] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + If invoked from within a plugin (e.g. `key-auth`) it would include the + namespace prefix, like so: + + ``` plain + 2017/07/09 19:36:25 [notice] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, body_filter, log + +**Parameters** + +* **...** : all params will be concatenated and stringified before being sent to the log + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.log("hello ", "world") -- alias to kong.log.notice() +``` + +[Back to top](#konglog) + + +### kong.log.LEVEL(...) + +Similar to `kong.log()`, but the produced log will have the severity given by + ``, instead of `notice`. The supported levels are: + + * `kong.log.alert()` + * `kong.log.crit()` + * `kong.log.err()` + * `kong.log.warn()` + * `kong.log.notice()` + * `kong.log.info()` + * `kong.log.debug()` + + Logs have the same format as that of `kong.log()`. For + example, the following call: + + ``` lua + kong.log.err("hello ", "world") + ``` + + would, within the core, produce a log line similar to: + + ``` plain + 2017/07/09 19:36:25 [error] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + If invoked from within a plugin (e.g. `key-auth`) it would include the + namespace prefix, like so: + + ``` plain + 2017/07/09 19:36:25 [error] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost" + ``` + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, body_filter, log + +**Parameters** + +* **...** : all params will be concatenated and stringified before being sent to the log + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.log.warn("something require attention") +kong.log.err("something failed: ", err) +kong.log.alert("something requires immediate action") +``` + +[Back to top](#konglog) + + +### kong.log.inspect(...) + +Like `kong.log()`, this function will produce a log with the `notice` level, + and accepts any number of arguments as well. If inspect logging is disabled + via `kong.log.inspect.off()`, then this function prints nothing, and is + aliased to a "NOP" function in order to save CPU cycles. + + ``` lua + kong.log.inspect("...") + ``` + + This function differs from `kong.log()` in the sense that arguments will be + concatenated with a space(`" "`), and each argument will be + "pretty-printed": + + * numbers will printed (e.g. `5` -> `"5"`) + * strings will be quoted (e.g. `"hi"` -> `'"hi"'`) + * array-like tables will be rendered (e.g. `{1,2,3}` -> `"{1, 2, 3}"`) + * dictionary-like tables will be rendered on multiple lines + + This function is intended for use with debugging purposes in mind, and usage + in production code paths should be avoided due to the expensive formatting + operations it can perform. Existing statements can be left in production code + but nopped by calling `kong.log.inspect.off()`. + + When writing logs, `kong.log.inspect()` always uses its own format, defined + as: + + ``` plain + %file_src:%func_name:%line_src %message + ``` + + Where: + + * `%file_src`: is the file name from where the log was called from. + * `%func_name`: is the name of the function from where the log was called + from. + * `%line_src`: is the line number from where the log was called from. + * `%message`: is the message, made of concatenated, pretty-printed arguments + given by the caller. + + This function uses the [inspect.lua](https://github.com/kikito/inspect.lua) + library to pretty-print its arguments. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, body_filter, log + +**Parameters** + +* **...** : Parameters will be concatenated with spaces between them and + rendered as described + +**Usage** + +``` lua +kong.log.inspect("some value", a_variable) +``` + +[Back to top](#konglog) + + +### kong.log.inspect.on() + +Enables inspect logs for this logging facility. Calls to + `kong.log.inspect` will be writing log lines with the appropriate + formatting of arguments. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, body_filter, log + +**Usage** + +``` lua +kong.log.inspect.on() +``` + +[Back to top](#konglog) + + +### kong.log.inspect.off() + +Disables inspect logs for this logging facility. All calls to + `kong.log.inspect()` will be nopped. + + +**Phases** + +* init_worker, certificate, rewrite, access, header_filter, body_filter, log + +**Usage** + +``` lua +kong.log.inspect.off() +``` + +[Back to top](#konglog) + + +### kong.log.serialize() + +Generates a table that contains information that are helpful for logging. + + This method can currently be used in the `http` subsystem. + + The following fields are included in the returned table: + * `client_ip` - client IP address in textual format. + * `latencies` - request/proxy latencies. + * `request.headers` - request headers. + * `request.method` - request method. + * `request.querystring` - request query strings. + * `request.size` - size of request. + * `request.url` and `request.uri` - URL and URI of request. + * `response.headers` - response headers. + * `response.size` - size of response. + * `response.status` - response HTTP status code. + * `route` - route object matched. + * `service` - service object used. + * `started_at` - timestamp this request came in, in milliseconds. + * `tries` - Upstream information; this is an array and if any balancer retries occurred, will contain more than one entry. + * `upstream_uri` - request URI sent to Upstream. + + The following fields are only present in an authenticated request (with consumer): + + * `authenticated_entity` - credential used for authentication. + * `consumer` - consumer entity accessing the resource. + + The following fields are only present in a TLS/HTTPS request: + * `request.tls.version` - TLS/SSL version used by the connection. + * `request.tls.cipher` - TLS/SSL cipher used by the connection. + * `request.tls.client_verify` - mTLS validation result. Contents are the same as described in [$ssl_client_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify). + + **Warning:** This function may return sensitive data (e.g., API keys). + Consider filtering before writing it to unsecured locations. + + To see what content is present in your setup, enable any of the logging + plugins (e.g., `file-log`) and the output written to the log file is the table + returned by this function JSON-encoded. + + +**Phases** + +* log + +**Returns** + +* `table` the request information table + + +**Usage** + +``` lua +kong.log.serialize() +``` + +[Back to top](#konglog) + diff --git a/app/2.2.x/pdk/kong.nginx.md b/app/2.2.x/pdk/kong.nginx.md new file mode 100644 index 000000000000..d95f09f73290 --- /dev/null +++ b/app/2.2.x/pdk/kong.nginx.md @@ -0,0 +1,42 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.nginx +pdk: true +toc: true +--- + +## kong.nginx + +Nginx information module + A set of functions allowing to retrieve Nginx-specific implementation + details and meta information. + + + +### kong.nginx.get_subsystem() + +Returns the current Nginx subsystem this function is called from: "http" + or "stream". + +**Phases** + +* any + +**Returns** + +* `string` subsystem Either `"http"` or `"stream"` + + +**Usage** + +``` lua +kong.nginx.get_subsystem() -- "http" +``` + +[Back to top](#kongnginx) + diff --git a/app/2.2.x/pdk/kong.node.md b/app/2.2.x/pdk/kong.node.md new file mode 100644 index 000000000000..8433482549e2 --- /dev/null +++ b/app/2.2.x/pdk/kong.node.md @@ -0,0 +1,111 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.node +pdk: true +toc: true +--- + +## kong.node + +Node-level utilities + + + +### kong.node.get_id() + +Returns the id used by this node to describe itself. + +**Returns** + +* `string` The v4 UUID used by this node as its id + + +**Usage** + +``` lua +local id = kong.node.get_id() +``` + +[Back to top](#kongnode) + + +### kong.node.get_memory_stats([unit[, scale]]) + +Returns memory usage statistics about this node. + +**Parameters** + +* **unit** (string, _optional_): The unit memory should be reported in. Can be + either of `b/B`, `k/K`, `m/M`, or `g/G` for bytes, kibibytes, mebibytes, + or gibibytes, respectively. Defaults to `b` (bytes). +* **scale** (number, _optional_): The number of digits to the right of the decimal + point. Defaults to 2. + +**Returns** + +* `table` A table containing memory usage statistics for this node. + If `unit` is `b/B` (the default) reported values will be Lua numbers. + Otherwise, reported values will be a string with the unit as a suffix. + + +**Usage** + +``` lua +local res = kong.node.get_memory_stats() +-- res will have the following structure: +{ + lua_shared_dicts = { + kong = { + allocated_slabs = 12288, + capacity = 24576 + }, + kong_db_cache = { + allocated_slabs = 12288, + capacity = 12288 + } + }, + workers_lua_vms = { + { + http_allocated_gc = 1102, + pid = 18004 + }, + { + http_allocated_gc = 1102, + pid = 18005 + } + } +} + +local res = kong.node.get_memory_stats("k", 1) +-- res will have the following structure: +{ + lua_shared_dicts = { + kong = { + allocated_slabs = "12.0 KiB", + capacity = "24.0 KiB", + }, + kong_db_cache = { + allocated_slabs = "12.0 KiB", + capacity = "12.0 KiB", + } + }, + workers_lua_vms = { + { + http_allocated_gc = "1.1 KiB", + pid = 18004 + }, + { + http_allocated_gc = "1.1 KiB", + pid = 18005 + } + } +} +``` + +[Back to top](#kongnode) + diff --git a/app/2.2.x/pdk/kong.request.md b/app/2.2.x/pdk/kong.request.md new file mode 100644 index 000000000000..7322caad5dc0 --- /dev/null +++ b/app/2.2.x/pdk/kong.request.md @@ -0,0 +1,686 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.request +pdk: true +toc: true +--- + +## kong.request + +Client request module + A set of functions to retrieve information about the incoming requests made + by clients. + + + +### kong.request.get_scheme() + +Returns the scheme component of the request's URL. The returned value is + normalized to lower-case form. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` a string like `"http"` or `"https"` + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies + +kong.request.get_scheme() -- "https" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_host() + +Returns the host component of the request's URL, or the value of the + "Host" header. The returned value is normalized to lower-case form. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the host + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies + +kong.request.get_host() -- "example.com" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_port() + +Returns the port component of the request's URL. The value is returned + as a Lua number. + + +**Phases** + +* certificate, rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `number` the port + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies + +kong.request.get_port() -- 1234 +``` + +[Back to top](#kongrequest) + + +### kong.request.get_forwarded_scheme() + +Returns the scheme component of the request's URL, but also considers + `X-Forwarded-Proto` if it comes from a trusted source. The returned + value is normalized to lower-case. + + Whether this function considers `X-Forwarded-Proto` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + + **Note**: support for the Forwarded HTTP Extension (RFC 7239) is not + offered yet since it is not supported by ngx\_http\_realip\_module. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the forwarded scheme + + +**Usage** + +``` lua +kong.request.get_forwarded_scheme() -- "https" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_forwarded_host() + +Returns the host component of the request's URL or the value of the "host" + header. Unlike `kong.request.get_host()`, this function will also consider + `X-Forwarded-Host` if it comes from a trusted source. The returned value + is normalized to lower-case. + + Whether this function considers `X-Forwarded-Host` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + + **Note**: we do not currently offer support for Forwarded HTTP Extension + (RFC 7239) since it is not supported by ngx_http_realip_module. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the forwarded host + + +**Usage** + +``` lua +kong.request.get_forwarded_host() -- "example.com" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_forwarded_port() + +Returns the port component of the request's URL, but also considers + `X-Forwarded-Host` if it comes from a trusted source. The value + is returned as a Lua number. + + Whether this function considers `X-Forwarded-Proto` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + + **Note**: we do not currently offer support for Forwarded HTTP Extension + (RFC 7239) since it is not supported by ngx_http_realip_module. + + When running Kong behind the L4 port mapping (or forwarding) you can also + configure: + * [port\_maps](https://getkong.org/docs/latest/configuration/#port_maps) + + `port_maps` configuration parameter enables this function to return the + port to which the port Kong is listening to is mapped to (in case they differ). + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `number` the forwarded port + + +**Usage** + +``` lua +kong.request.get_forwarded_port() -- 1234 +``` + +[Back to top](#kongrequest) + + +### kong.request.get_forwarded_path() + +Returns the path component of the request's URL, but also considers + `X-Forwarded-Path` if it comes from a trusted source. The value + is returned as a Lua string. + + Whether this function considers `X-Forwarded-Path` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + + **Note**: we do not currently do any normalization on the request path. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the forwarded path + + +**Usage** + +``` lua +kong.request.get_forwarded_path() -- /path +``` + +[Back to top](#kongrequest) + + +### kong.request.get_forwarded_prefix() + +Returns the prefix path component of the request's URL that Kong stripped + before proxying to upstream. It also checks if `X-Forwarded-Prefix` comes + from a trusted source, and uses it as is when given. The value is returned + as a Lua string. + + If a trusted `X-Forwarded-Prefix` is not passed, this function must be called after Kong has ran its router (`access` phase), + as the Kong router may strip the prefix of the request path. That stripped + path will become the return value of this function, unless there was already + a trusted `X-Forwarded-Prefix` header in the request. + + Whether this function considers `X-Forwarded-Prefix` or not depends on + several Kong configuration parameters: + + * [trusted\_ips](https://getkong.org/docs/latest/configuration/#trusted_ips) + * [real\_ip\_header](https://getkong.org/docs/latest/configuration/#real_ip_header) + * [real\_ip\_recursive](https://getkong.org/docs/latest/configuration/#real_ip_recursive) + + **Note**: we do not currently do any normalization on the request path prefix. + + +**Phases** + +* access + +**Returns** + +* `string|nil` the forwarded path prefix or nil if prefix was not stripped + + +**Usage** + +``` lua +kong.request.get_forwarded_prefix() -- /prefix +``` + +[Back to top](#kongrequest) + + +### kong.request.get_http_version() + +Returns the HTTP version used by the client in the request as a Lua + number, returning values such as `1`, `1.1`, `2.0`, or `nil` for + unrecognized values. + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `number|nil` the HTTP version as a Lua number + + +**Usage** + +``` lua +kong.request.get_http_version() -- 1.1 +``` + +[Back to top](#kongrequest) + + +### kong.request.get_method() + +Returns the HTTP method of the request. The value is normalized to + upper-case. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the request method + + +**Usage** + +``` lua +kong.request.get_method() -- "GET" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_path() + +Returns the path component of the request's URL. It is not normalized in + any way and does not include the querystring. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the path + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies?movie=foo + +kong.request.get_path() -- "/v1/movies" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_path_with_query() + +Returns the path, including the querystring if any. No + transformations/normalizations are done. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the path with the querystring + + +**Usage** + +``` lua +-- Given a request to https://example.com:1234/v1/movies?movie=foo + +kong.request.get_path_with_query() -- "/v1/movies?movie=foo" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_raw_query() + +Returns the query component of the request's URL. It is not normalized in + any way (not even URL-decoding of special characters) and does not + include the leading `?` character. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* string the query component of the request's URL + + +**Usage** + +``` lua +-- Given a request to https://example.com/foo?msg=hello%20world&bla=&bar + +kong.request.get_raw_query() -- "msg=hello%20world&bla=&bar" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_query_arg() + +Returns the value of the specified argument, obtained from the query + arguments of the current request. + + The returned value is either a `string`, a boolean `true` if an + argument was not given a value, or `nil` if no argument with `name` was + found. + + If an argument with the same name is present multiple times in the + querystring, this function will return the value of the first occurrence. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Returns** + +* `string|boolean|nil` the value of the argument + + +**Usage** + +``` lua +-- Given a request GET /test?foo=hello%20world&bar=baz&zzz&blo=&bar=bla&bar + +kong.request.get_query_arg("foo") -- "hello world" +kong.request.get_query_arg("bar") -- "baz" +kong.request.get_query_arg("zzz") -- true +kong.request.get_query_arg("blo") -- "" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_query([max_args]) + +Returns the table of query arguments obtained from the querystring. Keys + are query argument names. Values are either a string with the argument + value, a boolean `true` if an argument was not given a value, or an array + if an argument was given in the query string multiple times. Keys and + values are unescaped according to URL-encoded escaping rules. + + Note that a query string `?foo&bar` translates to two boolean `true` + arguments, and `?foo=&bar=` translates to two string arguments containing + empty strings. + + By default, this function returns up to **100** arguments. The optional + `max_args` argument can be specified to customize this limit, but must be + greater than **1** and not greater than **1000**. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Parameters** + +* **max_args** (number, _optional_): set a limit on the maximum number of parsed + arguments + +**Returns** + +* `table` A table representation of the query string + + +**Usage** + +``` lua +-- Given a request GET /test?foo=hello%20world&bar=baz&zzz&blo=&bar=bla&bar + +for k, v in pairs(kong.request.get_query()) do + kong.log.inspect(k, v) +end + +-- Will print +-- "foo" "hello world" +-- "bar" {"baz", "bla", true} +-- "zzz" true +-- "blo" "" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_header(name) + +Returns the value of the specified request header. + + The returned value is either a `string`, or can be `nil` if a header with + `name` was not found in the request. If a header with the same name is + present multiple times in the request, this function will return the value + of the first occurrence of this header. + + Header names in are case-insensitive and are normalized to lowercase, and + dashes (`-`) can be written as underscores (`_`); that is, the header + `X-Custom-Header` can also be retrieved as `x_custom_header`. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Parameters** + +* **name** (string): the name of the header to be returned + +**Returns** + +* `string|nil` the value of the header or nil if not present + + +**Usage** + +``` lua +-- Given a request with the following headers: + +-- Host: foo.com +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +kong.request.get_header("Host") -- "foo.com" +kong.request.get_header("x-custom-header") -- "bla" +kong.request.get_header("X-Another") -- "foo bar" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_headers([max_headers]) + +Returns a Lua table holding the request headers. Keys are header names. + Values are either a string with the header value, or an array of strings + if a header was sent multiple times. Header names in this table are + case-insensitive and are normalized to lowercase, and dashes (`-`) can be + written as underscores (`_`); that is, the header `X-Custom-Header` can + also be retrieved as `x_custom_header`. + + By default, this function returns up to **100** headers. The optional + `max_headers` argument can be specified to customize this limit, but must + be greater than **1** and not greater than **1000**. + + +**Phases** + +* rewrite, access, header_filter, body_filter, log, admin_api + +**Parameters** + +* **max_headers** (number, _optional_): set a limit on the maximum number of + parsed headers + +**Returns** + +* `table` the request headers in table form + + +**Usage** + +``` lua +-- Given a request with the following headers: + +-- Host: foo.com +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz +local headers = kong.request.get_headers() + +headers.host -- "foo.com" +headers.x_custom_header -- "bla" +headers.x_another[1] -- "foo bar" +headers["X-Another"][2] -- "baz" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_raw_body() + +Returns the plain request body. + + If the body has no size (empty), this function returns an empty string. + + If the size of the body is greater than the Nginx buffer size (set by + `client_body_buffer_size`), this function will fail and return an error + message explaining this limitation. + + +**Phases** + +* rewrite, access, admin_api + +**Returns** + +* `string` the plain request body + + +**Usage** + +``` lua +-- Given a body with payload "Hello, Earth!": + +kong.request.get_raw_body():gsub("Earth", "Mars") -- "Hello, Mars!" +``` + +[Back to top](#kongrequest) + + +### kong.request.get_body([mimetype[, max_args]]) + +Returns the request data as a key/value table. + A high-level convenience function. + The body is parsed with the most appropriate format: + + * If `mimetype` is specified: + * Decodes the body with the requested content type (if supported). + * If the request content type is `application/x-www-form-urlencoded`: + * Returns the body as form-encoded. + * If the request content type is `multipart/form-data`: + * Decodes the body as multipart form data + (same as `multipart(kong.request.get_raw_body(), + kong.request.get_header("Content-Type")):get_all()` ). + * If the request content type is `application/json`: + * Decodes the body as JSON + (same as `json.decode(kong.request.get_raw_body())`). + * JSON types are converted to matching Lua types. + * If none of the above, returns `nil` and an error message indicating the + body could not be parsed. + + The optional argument `mimetype` can be one of the following strings: + + * `application/x-www-form-urlencoded` + * `application/json` + * `multipart/form-data` + + The optional argument `max_args` can be used to set a limit on the number + of form arguments parsed for `application/x-www-form-urlencoded` payloads. + + The third return value is string containing the mimetype used to parsed + the body (as per the `mimetype` argument), allowing the caller to identify + what MIME type the body was parsed as. + + +**Phases** + +* rewrite, access, admin_api + +**Parameters** + +* **mimetype** (string, _optional_): the MIME type +* **max_args** (number, _optional_): set a limit on the maximum number of parsed + arguments + +**Returns** + +1. `table|nil` a table representation of the body + +1. `string|nil` an error message + +1. `string|nil` mimetype the MIME type used + + +**Usage** + +``` lua +local body, err, mimetype = kong.request.get_body() +body.name -- "John Doe" +body.age -- "42" +``` + +[Back to top](#kongrequest) + diff --git a/app/2.2.x/pdk/kong.response.md b/app/2.2.x/pdk/kong.response.md new file mode 100644 index 000000000000..427a2835a088 --- /dev/null +++ b/app/2.2.x/pdk/kong.response.md @@ -0,0 +1,572 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.response +pdk: true +toc: true +--- + +## kong.response + +Client response module + + The downstream response module contains a set of functions for producing and + manipulating responses sent back to the client ("downstream"). Responses can + be produced by Kong (e.g. an authentication plugin rejecting a request), or + proxied back from an Service's response body. + + Unlike `kong.service.response`, this module allows mutating the response + before sending it back to the client. + + + + +### kong.response.get_status() + +Returns the HTTP status code currently set for the downstream response (as + a Lua number). + + If the request was proxied (as per `kong.response.get_source()`), the + return value will be that of the response from the Service (identical to + `kong.service.response.get_status()`). + + If the request was _not_ proxied, and the response was produced by Kong + itself (i.e. via `kong.response.exit()`), the return value will be + returned as-is. + + +**Phases** + +* header_filter, body_filter, log, admin_api + +**Returns** + +* `number` status The HTTP status code currently set for the + downstream response + + +**Usage** + +``` lua +kong.response.get_status() -- 200 +``` + +[Back to top](#kongresponse) + + +### kong.response.get_header(name) + +Returns the value of the specified response header, as would be seen by + the client once received. + + The list of headers returned by this function can consist of both response + headers from the proxied Service _and_ headers added by Kong (e.g. via + `kong.response.add_header()`). + + The return value is either a `string`, or can be `nil` if a header with + `name` was not found in the response. If a header with the same name is + present multiple times in the request, this function will return the value + of the first occurrence of this header. + + +**Phases** + +* header_filter, body_filter, log, admin_api + +**Parameters** + +* **name** (string): The name of the header + + Header names are case-insensitive and dashes (`-`) can be written as + underscores (`_`); that is, the header `X-Custom-Header` can also be + retrieved as `x_custom_header`. + + +**Returns** + +* `string|nil` The value of the header + + +**Usage** + +``` lua +-- Given a response with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +kong.response.get_header("x-custom-header") -- "bla" +kong.response.get_header("X-Another") -- "foo bar" +kong.response.get_header("X-None") -- nil +``` + +[Back to top](#kongresponse) + + +### kong.response.get_headers([max_headers]) + +Returns a Lua table holding the response headers. Keys are header names. + Values are either a string with the header value, or an array of strings + if a header was sent multiple times. Header names in this table are + case-insensitive and are normalized to lowercase, and dashes (`-`) can be + written as underscores (`_`); that is, the header `X-Custom-Header` can + also be retrieved as `x_custom_header`. + + A response initially has no headers until a plugin short-circuits the + proxying by producing one (e.g. an authentication plugin rejecting a + request), or the request has been proxied, and one of the latter execution + phases is currently running. + + Unlike `kong.service.response.get_headers()`, this function returns *all* + headers as the client would see them upon reception, including headers + added by Kong itself. + + By default, this function returns up to **100** headers. The optional + `max_headers` argument can be specified to customize this limit, but must + be greater than **1** and not greater than **1000**. + + +**Phases** + +* header_filter, body_filter, log, admin_api + +**Parameters** + +* **max_headers** (number, _optional_): Limits how many headers are parsed + +**Returns** + +1. `table` headers A table representation of the headers in the + response + + +1. `string` err If more headers than `max_headers` were present, a + string with the error `"truncated"`. + + +**Usage** + +``` lua +-- Given an response from the Service with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +local headers = kong.response.get_headers() + +headers.x_custom_header -- "bla" +headers.x_another[1] -- "foo bar" +headers["X-Another"][2] -- "baz" +``` + +[Back to top](#kongresponse) + + +### kong.response.get_source() + +This function helps determining where the current response originated + from. Kong being a reverse proxy, it can short-circuit a request and + produce a response of its own, or the response can come from the proxied + Service. + + Returns a string with three possible values: + + * "exit" is returned when, at some point during the processing of the + request, there has been a call to `kong.response.exit()`. In other + words, when the request was short-circuited by a plugin or by Kong + itself (e.g. invalid credentials) + * "error" is returned when an error has happened while processing the + request - for example, a timeout while connecting to the upstream + service. + * "service" is returned when the response was originated by successfully + contacting the proxied Service. + + +**Phases** + +* header_filter, body_filter, log, admin_api + +**Returns** + +* `string` the source. + + +**Usage** + +``` lua +if kong.response.get_source() == "service" then + kong.log("The response comes from the Service") +elseif kong.response.get_source() == "error" then + kong.log("There was an error while processing the request") +elseif kong.response.get_source() == "exit" then + kong.log("There was an early exit while processing the request") +end +``` + +[Back to top](#kongresponse) + + +### kong.response.set_status(status) + +Allows changing the downstream response HTTP status code before sending it + to the client. + + This function should be used in the `header_filter` phase, as Kong is + preparing headers to be sent back to the client. + + +**Phases** + +* rewrite, access, header_filter, admin_api + +**Parameters** + +* **status** (number): The new status + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_status(404) +``` + +[Back to top](#kongresponse) + + +### kong.response.set_header(name, value) + +Sets a response header with the given value. This function overrides any + existing header with the same name. + + This function should be used in the `header_filter` phase, as Kong is + preparing headers to be sent back to the client. + +**Phases** + +* rewrite, access, header_filter, admin_api + +**Parameters** + +* **name** (string): The name of the header +* **value** (string|number|boolean): The new value for the header + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_header("X-Foo", "value") +``` + +[Back to top](#kongresponse) + + +### kong.response.add_header(name, value) + +Adds a response header with the given value. Unlike + `kong.response.set_header()`, this function does not remove any existing + header with the same name. Instead, another header with the same name will + be added to the response. If no header with this name already exists on + the response, then it is added with the given value, similarly to + `kong.response.set_header().` + + This function should be used in the `header_filter` phase, as Kong is + preparing headers to be sent back to the client. + +**Phases** + +* rewrite, access, header_filter, admin_api + +**Parameters** + +* **name** (string): The header name +* **value** (string|number|boolean): The header value + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.add_header("Cache-Control", "no-cache") +kong.response.add_header("Cache-Control", "no-store") +``` + +[Back to top](#kongresponse) + + +### kong.response.clear_header(name) + +Removes all occurrences of the specified header in the response sent to + the client. + + This function should be used in the `header_filter` phase, as Kong is + preparing headers to be sent back to the client. + + +**Phases** + +* rewrite, access, header_filter, admin_api + +**Parameters** + +* **name** (string): The name of the header to be cleared + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_header("X-Foo", "foo") +kong.response.add_header("X-Foo", "bar") + +kong.response.clear_header("X-Foo") +-- from here onwards, no X-Foo headers will exist in the response +``` + +[Back to top](#kongresponse) + + +### kong.response.set_headers(headers) + +Sets the headers for the response. Unlike `kong.response.set_header()`, + the `headers` argument must be a table in which each key is a string + (corresponding to a header's name), and each value is a string, or an + array of strings. + + This function should be used in the `header_filter` phase, as Kong is + preparing headers to be sent back to the client. + + The resulting headers are produced in lexicographical order. The order of + entries with the same name (when values are given as an array) is + retained. + + This function overrides any existing header bearing the same name as those + specified in the `headers` argument. Other headers remain unchanged. + + +**Phases** + +* rewrite, access, header_filter, admin_api + +**Parameters** + +* **headers** (table): + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +kong.response.set_headers({ + ["Bla"] = "boo", + ["X-Foo"] = "foo3", + ["Cache-Control"] = { "no-store", "no-cache" } +}) + +-- Will add the following headers to the response, in this order: +-- X-Bar: bar1 +-- Bla: boo +-- Cache-Control: no-store +-- Cache-Control: no-cache +-- X-Foo: foo3 +``` + +[Back to top](#kongresponse) + + +### kong.response.exit(status[, body[, headers]]) + +This function interrupts the current processing and produces a response. + It is typical to see plugins using it to produce a response before Kong + has a chance to proxy the request (e.g. an authentication plugin rejecting + a request, or a caching plugin serving a cached response). + + It is recommended to use this function in conjunction with the `return` + operator, to better reflect its meaning: + + ```lua + return kong.response.exit(200, "Success") + ``` + + Calling `kong.response.exit()` will interrupt the execution flow of + plugins in the current phase. Subsequent phases will still be invoked. + E.g. if a plugin called `kong.response.exit()` in the `access` phase, no + other plugin will be executed in that phase, but the `header_filter`, + `body_filter`, and `log` phases will still be executed, along with their + plugins. Plugins should thus be programmed defensively against cases when + a request was **not** proxied to the Service, but instead was produced by + Kong itself. + + The first argument `status` will set the status code of the response that + will be seen by the client. + + **In L4 proxy mode**, **only** the following status code are supported: + + * 200 - OK + * 400 - Bad request + * 403 - Forbidden + * 500 - Internal server error + * 502 - Bad gateway + * 503 - Service unavailable + + For **L4 proxy mode** the `status` code provided is primarily for logging + and statistical purpose, and is not visible to the client directly. + + The second, optional, `body` argument will set the response body. If it is + a string, no special processing will be done, and the body will be sent + as-is. It is the caller's responsibility to set the appropriate + Content-Type header via the third argument. As a convenience, `body` can + be specified as a table; in which case, it will be JSON-encoded and the + `application/json` Content-Type header will be set. On gRPC we cannot send + the `body` with this function at the moment at least, so what it does + instead is that it sends "body" in `grpc-message` header instead. If the + body is a table it looks for a field `message` in it, and uses that as a + `grpc-message` header. Though, if you have specified `Content-Type` header + starting with `application/grpc`, the body will be sent. + + **In L4 proxy mode**, `body` can only be `nil` or a string. Automatic JSON + encoding is not available. When provided, depends on the value of `status`, + the following will happen: + + When `status` is 500, 502 or 503, then `body` will be logged in the Kong + error log file. Otherwise `body` will be sent back to the L4 client. + + The third, optional, `headers` argument can be a table specifying response + headers to send. If specified, its behavior is similar to + `kong.response.set_headers()`. This argument is ignored in L4 proxy mode. + + Unless manually specified, this method will automatically set the + Content-Length header in the produced response for convenience. + +**Phases** + +* preread, rewrite, access, admin_api, header_filter (only if `body` is nil) + +**Parameters** + +* **status** (number): The status to be used +* **body** (table|string, _optional_): The body to be used +* **headers** (table, _optional_): The headers to be used + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +return kong.response.exit(403, "Access Forbidden", { + ["Content-Type"] = "text/plain", + ["WWW-Authenticate"] = "Basic" +}) + +--- + +return kong.response.exit(403, [[{"message":"Access Forbidden"}]], { + ["Content-Type"] = "application/json", + ["WWW-Authenticate"] = "Basic" +}) + +--- + +return kong.response.exit(403, { message = "Access Forbidden" }, { + ["WWW-Authenticate"] = "Basic" +}) + +--- + +```lua +-- In L4 proxy mode +return kong.response.exit(200, "Success") +``` +``` + +[Back to top](#kongresponse) + + +### kong.response.error(status[, message[, headers]]) + +This function interrupts the current processing and produces an error + response. + + It is recommended to use this function in conjunction with the `return` + operator, to better reflect its meaning: + + ```lua + return kong.response.error(500, "Error", {["Content-Type"] = "text/html"}) + ``` + + The first argument `status` will set the status code of the response that + will be seen by the client. The status code must be of an error, i.e. + >399. + + The second, optional, `message` argument will set the message describing + the error, which will be written in the body. + + The third, optional, `headers` argument can be a table specifying response + headers to send. If specified, its behavior is similar to + `kong.response.set_headers()`. + + This method will send the response formatted in JSON, XML, HTML or plain + text. The actual format is chosen using one of the following options: + - Manually specifying in `headers` argument using the `Content-Type` + header. + - Conform to the `Accept` header from the request. + - If none of the above is found, fallback to JSON format. + Content-Length header in the produced response for convenience. + +**Phases** + +* rewrite, access, admin_api, header_filter (only if `body` is nil) + +**Parameters** + +* **status** (number): The status to be used (>399) +* **message** (string, _optional_): The error message to be used +* **headers** (table, _optional_): The headers to be used + +**Returns** + +* Nothing; throws an error on invalid input. + + +**Usage** + +``` lua +return kong.response.error(403, "Access Forbidden", { + ["Content-Type"] = "text/plain", + ["WWW-Authenticate"] = "Basic" +}) + +--- + +return kong.response.error(403, "Access Forbidden") + +--- + +return kong.response.error(403) +``` + +[Back to top](#kongresponse) + diff --git a/app/2.2.x/pdk/kong.router.md b/app/2.2.x/pdk/kong.router.md new file mode 100644 index 000000000000..e02646c385a9 --- /dev/null +++ b/app/2.2.x/pdk/kong.router.md @@ -0,0 +1,71 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.router +pdk: true +toc: true +--- + +## kong.router + +Router module + A set of functions to access the routing properties of the request. + + + +### kong.router.get_route() + +Returns the current `route` entity. The request was matched against this + route. + + +**Phases** + +* access, header_filter, body_filter, log + +**Returns** + +* `table` the `route` entity. + + +**Usage** + +``` lua +local route = kong.router.get_route() +local protocols = route.protocols +``` + +[Back to top](#kongrouter) + + +### kong.router.get_service() + +Returns the current `service` entity. The request will be targetted to this + upstream service. + + +**Phases** + +* access, header_filter, body_filter, log + +**Returns** + +* `table` the `service` entity. + + +**Usage** + +``` lua +if kong.router.get_service() then + -- routed by route & service entities +else + -- routed by a route without a service +end +``` + +[Back to top](#kongrouter) + diff --git a/app/2.2.x/pdk/kong.service.md b/app/2.2.x/pdk/kong.service.md new file mode 100644 index 000000000000..2c5e329946fb --- /dev/null +++ b/app/2.2.x/pdk/kong.service.md @@ -0,0 +1,256 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.service +pdk: true +toc: true +--- + +## kong.service + +The service module contains a set of functions to manipulate the connection + aspect of the request to the Service, such as connecting to a given host, IP + address/port, or choosing a given Upstream entity for load-balancing and + healthchecking. + + + +### kong.service.set_upstream(host) + +Sets the desired Upstream entity to handle the load-balancing step for + this request. Using this method is equivalent to creating a Service with a + `host` property equal to that of an Upstream entity (in which case, the + request would be proxied to one of the Targets associated with that + Upstream). + + The `host` argument should receive a string equal to that of one of the + Upstream entities currently configured. + + +**Phases** + +* access + +**Parameters** + +* **host** (string): + +**Returns** + +1. `boolean|nil` `true` on success, or `nil` if no upstream entities + where found + +1. `string|nil` An error message describing the error if there was + one. + + + +**Usage** + +``` lua +local ok, err = kong.service.set_upstream("service.prod") +if not ok then + kong.log.err(err) + return +end +``` + +[Back to top](#kongservice) + + +### kong.service.set_target(host, port) + +Sets the host and port on which to connect to for proxying the request. + Using this method is equivalent to ask Kong to not run the load-balancing + phase for this request, and consider it manually overridden. + Load-balancing components such as retries and health-checks will also be + ignored for this request. + + The `host` argument expects a string containing the IP address of the + upstream server (IPv4/IPv6), and the `port` argument must contain a number + representing the port on which to connect to. + + +**Phases** + +* access + +**Parameters** + +* **host** (string): +* **port** (number): + +**Usage** + +``` lua +kong.service.set_target("service.local", 443) +kong.service.set_target("192.168.130.1", 80) +``` + +[Back to top](#kongservice) + + +### kong.service.set_tls_cert_key(chain, key) + +Sets the client certificate used while handshaking with the Service. + + The `chain` argument is the client certificate and intermediate chain (if any) + returned by functions such as [ngx.ssl.parse\_pem\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_cert). + + The `key` argument is the private key corresponding to the client certificate + returned by functions such as [ngx.ssl.parse\_pem\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_priv_key). + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **chain** (cdata): The client certificate chain +* **key** (cdata): The client certificate private key + +**Returns** + +1. `boolean|nil` `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil` An error message describing the error if there was one + + +**Usage** + +``` lua +local chain = assert(ssl.parse_pem_cert(cert_data)) +local key = assert(ssl.parse_pem_priv_key(key_data)) + +local ok, err = kong.service.set_tls_cert_key(chain, key) +if not ok then + -- do something with error +end +``` + +[Back to top](#kongservice) + + +### kong.service.set_tls_verify(on) + +Sets whether TLS verification is enabled while handshaking with the Service. + + The `on` argument is a boolean flag, where `true` means upstream verification + is enabled and `false` disables it. + + This call affects only the current request. If the trusted certificate store is + not set already (via [proxy_ssl_trusted_certificate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_trusted_certificate) + or [kong.service.set_upstream_ssl_trusted_store](#kongserviceset_upstream_ssl_trusted_store)), + then TLS verification will always fail with "unable to get local issuer certificate" error. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **on** (boolean): Whether to enable TLS certificate verification for the current request + +**Returns** + +1. `boolean|nil` `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil` An error message describing the error if there was one + + +**Usage** + +``` lua +local ok, err = kong.service.set_tls_verify(true) +if not ok then + -- do something with error +end +``` + +[Back to top](#kongservice) + + +### kong.service.set_tls_verify_depth(depth) + +Sets the maximum depth of verification when validating upstream server's TLS certificate. + + This call affects only the current request. For the depth to be actually used the verification + has to be enabled with either the [proxy_ssl_verify](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify) + directive or using the [kong.service.set_tls_verify](#kongserviceset_tls_verify) function. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **depth** (number): Depth to use when validating. Must be non-negative + +**Returns** + +1. `boolean|nil` `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil` An error message describing the error if there was one + + +**Usage** + +``` lua +local ok, err = kong.service.set_tls_verify_depth(3) +if not ok then + -- do something with error +end +``` + +[Back to top](#kongservice) + + +### kong.service.set_tls_verify_store(store) + +Sets the CA trust store to use when validating upstream server's TLS certificate. + + This call affects only the current request. For the store to be actually used the verification + has to be enabled with either the [proxy_ssl_verify](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify) + directive or using the [kong.service.set_tls_verify](#kongserviceset_tls_verify) function. + + The resty.openssl.x509.store object can be created by following + [examples](https://github.com/Kong/lua-kong-nginx-module#restykongtlsset_upstream_ssl_trusted_store) from the Kong/lua-kong-nginx-module repo. + + +**Phases** + +* `rewrite`, `access`, `balancer` + +**Parameters** + +* **store** (table): resty.openssl.x509.store object to use + +**Returns** + +1. `boolean|nil` `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil` An error message describing the error if there was one + + +**Usage** + +``` lua +local store = require("resty.openssl.x509.store") +local st = assert(store.new()) +-- st:add(...certificate) + +local ok, err = kong.service.set_tls_verify_store(st) +if not ok then + -- do something with error +end +``` + +[Back to top](#kongservice) + diff --git a/app/2.2.x/pdk/kong.service.request.md b/app/2.2.x/pdk/kong.service.request.md new file mode 100644 index 000000000000..4f9776086c61 --- /dev/null +++ b/app/2.2.x/pdk/kong.service.request.md @@ -0,0 +1,498 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.service.request +pdk: true +toc: true +--- + +## kong.service.request + +Manipulation of the request to the Service + + + +### kong.service.request.enable_buffering() + +Enables buffered proxying that allows plugins to access service body and + response headers at the same time + +**Phases** + +* `rewrite`, `access` + +**Returns** + +* Nothing + + +**Usage** + +``` lua +kong.service.request.enable_buffering() +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_scheme(scheme) + +Sets the protocol to use when proxying the request to the Service. + +**Phases** + +* `access` + +**Parameters** + +* **scheme** (string): The scheme to be used. Supported values are `"http"` or `"https"` + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_scheme("https") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_path(path) + +Sets the path component for the request to the service. It is not + normalized in any way and should **not** include the querystring. + +**Phases** + +* `access` + +**Parameters** + +* **path** : The path string. Example: "/v2/movies" + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_path("/v2/movies") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_raw_query(query) + +Sets the querystring of the request to the Service. The `query` argument is a + string (without the leading `?` character), and will not be processed in any + way. + + For a higher-level function to set the query string from a Lua table of + arguments, see `kong.service.request.set_query()`. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **query** (string): The raw querystring. Example: "foo=bar&bla&baz=hello%20world" + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_raw_query("zzz&bar=baz&bar=bla&bar&blo=&foo=hello%20world") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_method(method) + +Sets the HTTP method for the request to the service. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **method** : The method string, which should be given in all + uppercase. Supported values are: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`, + `"DELETE"`, `"OPTIONS"`, `"MKCOL"`, `"COPY"`, `"MOVE"`, `"PROPFIND"`, + `"PROPPATCH"`, `"LOCK"`, `"UNLOCK"`, `"PATCH"`, `"TRACE"`. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_method("DELETE") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_query(args) + +Set the querystring of the request to the Service. + + Unlike `kong.service.request.set_raw_query()`, the `query` argument must be a + table in which each key is a string (corresponding to an arguments name), and + each value is either a boolean, a string or an array of strings or booleans. + Additionally, all string values will be URL-encoded. + + The resulting querystring will contain keys in their lexicographical order. The + order of entries within the same key (when values are given as an array) is + retained. + + If further control of the querystring generation is needed, a raw querystring + can be given as a string with `kong.service.request.set_raw_query()`. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **args** (table): A table where each key is a string (corresponding to an + argument name), and each value is either a boolean, a string or an array of + strings or booleans. Any string values given are URL-encoded. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_query({ + foo = "hello world", + bar = {"baz", "bla", true}, + zzz = true, + blo = "" +}) +-- Will produce the following query string: +-- bar=baz&bar=bla&bar&blo=&foo=hello%20world&zzz +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_header(header, value) + +Sets a header in the request to the Service with the given value. Any existing header + with the same name will be overridden. + + If the `header` argument is `"host"` (case-insensitive), then this is + will also set the SNI of the request to the Service. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **header** (string): The header name. Example: "X-Foo" +* **value** (string|boolean|number): The header value. Example: "hello world" + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_header("X-Foo", "value") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.add_header(header, value) + +Adds a request header with the given value to the request to the Service. Unlike + `kong.service.request.set_header()`, this function will not remove any existing + headers with the same name. Instead, several occurences of the header will be + present in the request. The order in which headers are added is retained. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **header** (string): The header name. Example: "Cache-Control" +* **value** (string|number|boolean): The header value. Example: "no-cache" + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.add_header("Cache-Control", "no-cache") +kong.service.request.add_header("Cache-Control", "no-store") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.clear_header(header) + +Removes all occurrences of the specified header in the request to the Service. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **header** (string): The header name. Example: "X-Foo" + +**Returns** + +* Nothing; throws an error on invalid inputs. + The function does not throw an error if no header was removed. + + +**Usage** + +``` lua +kong.service.request.set_header("X-Foo", "foo") +kong.service.request.add_header("X-Foo", "bar") +kong.service.request.clear_header("X-Foo") +-- from here onwards, no X-Foo headers will exist in the request +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_headers(headers) + +Sets the headers of the request to the Service. Unlike + `kong.service.request.set_header()`, the `headers` argument must be a table in + which each key is a string (corresponding to a header's name), and each value + is a string, or an array of strings. + + The resulting headers are produced in lexicographical order. The order of + entries with the same name (when values are given as an array) is retained. + + This function overrides any existing header bearing the same name as those + specified in the `headers` argument. Other headers remain unchanged. + + If the `"Host"` header is set (case-insensitive), then this is + will also set the SNI of the request to the Service. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **headers** (table): A table where each key is a string containing a header name + and each value is either a string or an array of strings. + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_header("X-Foo", "foo1") +kong.service.request.add_header("X-Foo", "foo2") +kong.service.request.set_header("X-Bar", "bar1") +kong.service.request.set_headers({ + ["X-Foo"] = "foo3", + ["Cache-Control"] = { "no-store", "no-cache" }, + ["Bla"] = "boo" +}) + +-- Will add the following headers to the request, in this order: +-- X-Bar: bar1 +-- Bla: boo +-- Cache-Control: no-store +-- Cache-Control: no-cache +-- X-Foo: foo3 +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_raw_body(body) + +Sets the body of the request to the Service. + + The `body` argument must be a string and will not be processed in any way. + This function also sets the `Content-Length` header appropriately. To set an + empty body, one can give an empty string `""` to this function. + + For a higher-level function to set the body based on the request content type, + see `kong.service.request.set_body()`. + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **body** (string): The raw body + +**Returns** + +* Nothing; throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.request.set_raw_body("Hello, world!") +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.set_body(args[, mimetype]) + +Sets the body of the request to the Service. Unlike + `kong.service.request.set_raw_body()`, the `args` argument must be a table, and + will be encoded with a MIME type. The encoding MIME type can be specified in + the optional `mimetype` argument, or if left unspecified, will be chosen based + on the `Content-Type` header of the client's request. + + If the MIME type is `application/x-www-form-urlencoded`: + + * Encodes the arguments as form-encoded: keys are produced in lexicographical + order. The order of entries within the same key (when values are + given as an array) is retained. Any string values given are URL-encoded. + + If the MIME type is `multipart/form-data`: + + * Encodes the arguments as multipart form data. + + If the MIME type is `application/json`: + + * Encodes the arguments as JSON (same as + `kong.service.request.set_raw_body(json.encode(args))`) + * Lua types are converted to matching JSON types.mej + + If none of the above, returns `nil` and an error message indicating the + body could not be encoded. + + The optional argument `mimetype` can be one of: + + * `application/x-www-form-urlencoded` + * `application/json` + * `multipart/form-data` + + If the `mimetype` argument is specified, the `Content-Type` header will be + set accordingly in the request to the Service. + + If further control of the body generation is needed, a raw body can be given as + a string with `kong.service.request.set_raw_body()`. + + +**Phases** + +* `rewrite`, `access` + +**Parameters** + +* **args** (table): A table with data to be converted to the appropriate format + and stored in the body. +* **mimetype** (string, _optional_): can be one of: + +**Returns** + +1. `boolean|nil` `true` on success, `nil` otherwise + +1. `string|nil` `nil` on success, an error message in case of error. + Throws an error on invalid inputs. + + +**Usage** + +``` lua +kong.service.set_header("application/json") +local ok, err = kong.service.request.set_body({ + name = "John Doe", + age = 42, + numbers = {1, 2, 3} +}) + +-- Produces the following JSON body: +-- { "name": "John Doe", "age": 42, "numbers":[1, 2, 3] } + +local ok, err = kong.service.request.set_body({ + foo = "hello world", + bar = {"baz", "bla", true}, + zzz = true, + blo = "" +}, "application/x-www-form-urlencoded") + +-- Produces the following body: +-- bar=baz&bar=bla&bar&blo=&foo=hello%20world&zzz +``` + +[Back to top](#kongservicerequest) + + +### kong.service.request.disable_tls() + +Disables the TLS handshake to upstream for [ngx\_stream\_proxy\_module](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html). + Effectively this overrides [proxy\_ssl](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl) directive to `off` setting + for the current stream session. + + Note that once this function has been called it is not possible to re-enable TLS handshake for the current session. + + +**Phases** + +* `preread`, `balancer` + +**Returns** + +1. `boolean|nil` `true` if the operation succeeded, `nil` if an error occurred + +1. `string|nil` An error message describing the error if there was one. + + +**Usage** + +``` lua +local ok, err = kong.service.request.disable_tls() +if not ok then + -- do something with error +end +``` + +[Back to top](#kongservicerequest) + diff --git a/app/2.2.x/pdk/kong.service.response.md b/app/2.2.x/pdk/kong.service.response.md new file mode 100644 index 000000000000..a9ca6a82c340 --- /dev/null +++ b/app/2.2.x/pdk/kong.service.response.md @@ -0,0 +1,194 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.service.response +pdk: true +toc: true +--- + +## kong.service.response + +Manipulation of the response from the Service + + + +### kong.service.response.get_status() + +Returns the HTTP status code of the response from the Service as a Lua number. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Returns** + +* `number|nil` the status code from the response from the Service, or `nil` + if the request was not proxied (i.e. `kong.response.get_source()` returned + anything other than `"service"`. + + +**Usage** + +``` lua +kong.log.inspect(kong.service.response.get_status()) -- 418 +``` + +[Back to top](#kongserviceresponse) + + +### kong.service.response.get_headers([max_headers]) + +Returns a Lua table holding the headers from the response from the Service. Keys are + header names. Values are either a string with the header value, or an array of + strings if a header was sent multiple times. Header names in this table are + case-insensitive and dashes (`-`) can be written as underscores (`_`); that is, + the header `X-Custom-Header` can also be retrieved as `x_custom_header`. + + Unlike `kong.response.get_headers()`, this function will only return headers that + were present in the response from the Service (ignoring headers added by Kong itself). + If the request was not proxied to a Service (e.g. an authentication plugin rejected + a request and produced an HTTP 401 response), then the returned `headers` value + might be `nil`, since no response from the Service has been received. + + By default, this function returns up to **100** headers. The optional + `max_headers` argument can be specified to customize this limit, but must be + greater than **1** and not greater than **1000**. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Parameters** + +* **max_headers** (number, _optional_): customize the headers to parse + +**Returns** + +1. `table` the response headers in table form + +1. `string` err If more headers than `max_headers` were present, a + string with the error `"truncated"`. + + +**Usage** + +``` lua +-- Given a response with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz +local headers = kong.service.response.get_headers() +if headers then + kong.log.inspect(headers.x_custom_header) -- "bla" + kong.log.inspect(headers.x_another[1]) -- "foo bar" + kong.log.inspect(headers["X-Another"][2]) -- "baz" +end +``` + +[Back to top](#kongserviceresponse) + + +### kong.service.response.get_header(name) + +Returns the value of the specified response header. + + Unlike `kong.response.get_header()`, this function will only return a header + if it was present in the response from the Service (ignoring headers added by Kong + itself). + + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Parameters** + +* **name** (string): The name of the header. + + Header names in are case-insensitive and are normalized to lowercase, and + dashes (`-`) can be written as underscores (`_`); that is, the header + `X-Custom-Header` can also be retrieved as `x_custom_header`. + + +**Returns** + +* `string|nil` The value of the header, or `nil` if a header with + `name` was not found in the response. If a header with the same name is present + multiple times in the response, this function will return the value of the + first occurrence of this header. + + +**Usage** + +``` lua +-- Given a response with the following headers: +-- X-Custom-Header: bla +-- X-Another: foo bar +-- X-Another: baz + +kong.log.inspect(kong.service.response.get_header("x-custom-header")) -- "bla" +kong.log.inspect(kong.service.response.get_header("X-Another")) -- "foo bar" +``` + +[Back to top](#kongserviceresponse) + + +### kong.service.response.get_raw_body() + +Returns the raw buffered body. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Returns** + +* `string` body The raw buffered body + + +**Usage** + +``` lua +-- Plugin needs to call kong.service.request.enable_buffering() on `rewrite` +-- or `access` phase prior calling this function. + +local body = kong.service.response.get_raw_body() +``` + +[Back to top](#kongserviceresponse) + + +### kong.service.response.get_body(mimetype[, mimetype[, max_args]]) + +Returns the decoded buffered body. + +**Phases** + +* `header_filter`, `body_filter`, `log` + +**Parameters** + +* **mimetype** (string, _optional_): the MIME type +* **mimetype** (string, _optional_): the MIME type +* **max_args** (number, _optional_): set a limit on the maximum number of parsed + +**Returns** + +* `string` body The raw buffered body + + +**Usage** + +``` lua +-- Plugin needs to call kong.service.request.enable_buffering() on `rewrite` +-- or `access` phase prior calling this function. + +local body = kong.service.response.get_body() +``` + +[Back to top](#kongserviceresponse) + diff --git a/app/2.2.x/pdk/kong.table.md b/app/2.2.x/pdk/kong.table.md new file mode 100644 index 000000000000..95e05a4c6145 --- /dev/null +++ b/app/2.2.x/pdk/kong.table.md @@ -0,0 +1,73 @@ +--- +# +# WARNING: this file was auto-generated by a script. +# DO NOT edit this file directly. Instead, send a pull request to change +# https://github.com/Kong/kong/tree/master/autodoc/pdk/ldoc/ldoc.ltp +# or its associated files +# +title: kong.table +pdk: true +toc: true +--- + +## kong.table + +Utilities for Lua tables + + + +### kong.table.new([narr[, nrec]]) + +Returns a table with pre-allocated number of slots in its array and hash + parts. + +**Parameters** + +* **narr** (number, _optional_): specifies the number of slots to pre-allocate + in the array part. +* **nrec** (number, _optional_): specifies the number of slots to pre-allocate in + the hash part. + +**Returns** + +* `table` the newly created table + + +**Usage** + +``` lua +local tab = kong.table.new(4, 4) +``` + +[Back to top](#kongtable) + + +### kong.table.clear(tab) + +Clears a table from all of its array and hash parts entries. + +**Parameters** + +* **tab** (table): the table which will be cleared + +**Returns** + +* Nothing + + +**Usage** + +``` lua +local tab = { + "hello", + foo = "bar" +} + +kong.table.clear(tab) + +kong.log(tab[1]) -- nil +kong.log(tab.foo) -- nil +``` + +[Back to top](#kongtable) + diff --git a/app/2.2.x/plugin-development/access-the-datastore.md b/app/2.2.x/plugin-development/access-the-datastore.md new file mode 100644 index 000000000000..63fab7c8aa5c --- /dev/null +++ b/app/2.2.x/plugin-development/access-the-datastore.md @@ -0,0 +1,75 @@ +--- +title: Plugin Development - Accessing the Datastore +book: plugin_dev +chapter: 5 +--- + +## Introduction + +Kong interacts with the model layer through classes we refer to as "DAOs". This +chapter will detail the available API to interact with the datastore. + +Kong supports two primary datastores: [Cassandra +{{site.data.kong_latest.dependencies.cassandra}}](http://cassandra.apache.org/) +and [PostgreSQL +{{site.data.kong_latest.dependencies.postgres}}](http://www.postgresql.org/). + +## kong.db + +All entities in Kong are represented by: + +- A schema that describes which table the entity relates to in the datastore, + constraints on its fields such as foreign keys, non-null constraints etc. + This schema is a table described in the [plugin configuration]({{page.book.chapters.plugin-configuration}}) + chapter. +- An instance of the `DAO` class mapping to the database currently in use + (Cassandra or Postgres). This class' methods consume the schema and expose + methods to insert, update, select and delete entities of that type. + +The core entities in Kong are: Services, Routes, Consumers and Plugins. +All of them are accessible as Data Access Objects (DAOs), +through the `kong.db` global singleton: + + +```lua +-- Core DAOs +local services = kong.db.services +local routes = kong.db.routes +local consumers = kong.db.consumers +local plugins = kong.db.plugins +``` + +Both core entities from Kong and custom entities from plugins are +available through `kong.db.*`. + +--- + +## The DAO Lua API + +The DAO class is responsible for the operations executed on a given table in +the datastore, generally mapping to an entity in Kong. All the underlying +supported databases (currently Cassandra and Postgres) comply to the same +interface, thus making the DAO compatible with all of them. + +For example, inserting a Service and a Plugin is as easy as: + +```lua +local inserted_service, err = kong.db.services:insert({ + name = "mockbin", + url = "http://mockbin.org", +}) + +local inserted_plugin, err = kong.db.plugins:insert({ + name = "key-auth", + service = inserted_service, +}) +``` + +For a real-life example of the DAO being used in a plugin, see the +[Key-Auth plugin source code](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). + +--- + +Next: [Storing Custom Entities ›]({{page.book.next}}) + +[Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/2.2.x/plugin-development/admin-api.md b/app/2.2.x/plugin-development/admin-api.md new file mode 100644 index 000000000000..951393ac2e8d --- /dev/null +++ b/app/2.2.x/plugin-development/admin-api.md @@ -0,0 +1,179 @@ +--- +title: Plugin Development - Extending the Admin API +book: plugin_dev +chapter: 8 +--- + +
+ Note: This chapter assumes that you have a relative + knowledge of Lapis. +
+ +
+ Note: The Admin API extensions are available only + for HTTP plugins, not Stream plugins. +
+ +## Introduction + +Kong can be configured using a REST interface referred to as the [Admin API]. +Plugins can extend it by adding their own endpoints to accommodate custom +entities or other personalized management needs. A typical example of this is +the creation, retrieval, and deletion (commonly referred to as "CRUD +operations") of API keys. + +The Admin API is a [Lapis](http://leafo.net/lapis/) application, and Kong's +level of abstraction makes it easy for you to add endpoints. + +## Module + +``` +kong.plugins..api +``` + +## Adding endpoints to the Admin API + +Kong will detect and load your endpoints if they are defined in a module named: + +``` +"kong.plugins..api" +``` + +This module is bound to return a table with one or more entries with the following structure: + +``` lua +{ + [""] = { + schema = , + methods = { + before = function(self) ... end, + on_error = function(self) ... end, + GET = function(self) ... end, + PUT = function(self) ... end, + ... + } + }, + ... +} +``` + +Where: + +- `` should be a string representing a route like `/users` (See [Lapis routes & URL + Patterns](http://leafo.net/lapis/reference/actions.html#routes--url-patterns)) for details. + Notice that the path can contain interpolation parameters, like `/users/:users/new`. +- `` is a schema definition. Schemas for core and custom plugin entities are available + via `kong.db..schema`. The schema is used to parse certain fields according to their + types; for example if a field is marked as an integer, it will be parsed as such when it is + passed to a function (by default form fields are all strings). +- The `methods` subtable contains functions, indexed by a string. + - The `before` key is optional and can hold a function. If present, the function will be executed + on every request that hits `path`, before any other function is invoked. + - One or more functions can be indexed with HTTP method names, like `GET` or `PUT`. These functions + will be executed when the appropriate HTTP method and `path` is matched. If a `before` function is + present on the `path`, it will be executed first. Keep in mind that `before` functions can + use `kong.response.exit` to finish early, effectively cancelling the "regular" http method function. + - The `on_error` key is optional and can hold a function. If present, the function will be executed + when the code from other functions (either from a `before` or a "http method") throws an error. If + not present, then Kong will use a default error handler to return the errors. + +For example: + +``` lua +local endpoints = require "kong.api.endpoints" + +local credentials_schema = kong.db.keyauth_credentials.schema +local consumers_schema = kong.db.consumers.schema + +return { + ["/consumers/:consumers/key-auth"] = { + schema = credentials_schema, + methods = { + GET = endpoints.get_collection_endpoint( + credentials_schema, consumers_schema, "consumer"), + + POST = endpoints.post_collection_endpoint( + credentials_schema, consumers_schema, "consumer"), + }, + }, +} +``` + +This code will create two Admin API endpoints in `/consumers/:consumers/key-auth`, to +obtain (`GET`) and create (`POST`) credentials associated to a given consumer. On this example +the functions are provided by the `kong.api.endpoints` library. If you want to see a more +complete example, with custom code in functions, see +[the `api.lua` file from the key-auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/api.lua). + +The `endpoints` module currently contains the default implementation for the most usual CRUD +operations used in Kong. This module provides you with helpers for any insert, retrieve, +update or delete operations and performs the necessary DAO operations and replies with +the appropriate HTTP status codes. It also provides you with functions to retrieve parameters from +the path, such as an Service's name or id, or a Consumer's username or id. + +If `endpoints`-provided are functions not enough, a regular Lua function can be used instead. From there you can use: + +- Several functions provided by the `endpoints` module. +- All the functionality provided by the [PDK](../../pdk) +- The `self` parameter, which is the [Lapis request object](http://leafo.net/lapis/reference/actions.html#request-object). +- And of course you can `require` any Lua modules if needed. Make sure they are compatible with OpenResty if you choose this route. + +``` lua +local endpoints = require "kong.api.endpoints" + +local credentials_schema = kong.db.keyauth_credentials.schema +local consumers_schema = kong.db.consumers.schema + +return { + ["/consumers/:consumers/key-auth/:keyauth_credentials"] = { + schema = credentials_schema, + methods = { + before = function(self, db, helpers) + local consumer, _, err_t = endpoints.select_entity(self, db, consumers_schema) + if err_t then + return endpoints.handle_error(err_t) + end + if not consumer then + return kong.response.exit(404, { message = "Not found" }) + end + + self.consumer = consumer + + if self.req.method ~= "PUT" then + local cred, _, err_t = endpoints.select_entity(self, db, credentials_schema) + if err_t then + return endpoints.handle_error(err_t) + end + + if not cred or cred.consumer.id ~= consumer.id then + return kong.response.exit(404, { message = "Not found" }) + end + self.keyauth_credential = cred + self.params.keyauth_credentials = cred.id + end + end, + GET = endpoints.get_entity_endpoint(credentials_schema), + PUT = function(self, db, helpers) + self.args.post.consumer = { id = self.consumer.id } + return endpoints.put_entity_endpoint(credentials_schema)(self, db, helpers) + end, + }, + }, +} +``` + +On the previous example, the `/consumers/:consumers/key-auth/:keyauth_credentials` path gets +three functions: +- The `before` function is a custom Lua function which uses several `endpoints`-provided utilities + (`endpoints.handle_error`) as well as PDK functions (`kong.response.exit`). It also populates + `self.consumer` for the subsequent functions to use. +- The `GET` function is built entirely using `endpoints`. This is possible because the `before` has + "prepared" things in advance, like `self.consumer`. +- The `PUT` function populates `self.args.post.consumer` before calling the `endpoints`-provided + `put_entity_endpoint` function. + +--- + +Next: [Write tests for your plugin]({{page.book.next}}) + +[Admin API]: /{{page.kong_version}}/admin-api/ diff --git a/app/2.2.x/plugin-development/custom-entities.md b/app/2.2.x/plugin-development/custom-entities.md new file mode 100644 index 000000000000..89b69291a42b --- /dev/null +++ b/app/2.2.x/plugin-development/custom-entities.md @@ -0,0 +1,680 @@ +--- +title: Plugin Development - Storing Custom Entities +book: plugin_dev +chapter: 6 +--- + +## Introduction + +While not all plugins need it, your plugin might need to store more than +its configuration in the database. In that case, Kong provides you with +an abstraction on top of its primary datastores which allows you to store +custom entities. + +As explained in the [previous chapter]({{page.book.previous}}), Kong interacts +with the model layer through classes we refer to as "DAOs", and available on a +singleton often referred to as the "DAO Factory". This chapter will explain how +to to provide an abstraction for your own entities. + +## Modules + +``` +kong.plugins..daos +kong.plugins..migrations.init +kong.plugins..migrations.000_base_ +kong.plugins..migrations.001__to_ +kong.plugins..migrations.002__to_ +``` + +## Create the migrations folder + +Once you have defined your model, you must create your migration modules which +will be executed by Kong to create the table in which your records of your +entity will be stored. + +If your plugin is intended to support both Cassandra and Postgres, then both +migrations must be written. + +If your plugin doesn't have it already, you should add a `/migrations` +folder to it. If there is no `init.lua` file inside already, you should create one. +This is where all the migrations for your plugin will be referenced. + +The initial version of your `migrations/init.lua` file will point to a single migration. + +In this case we have called it `000_base_my_plugin`. + +``` lua +-- `migrations/init.lua` +return { + "000_base_my_plugin", +} +``` + +This means that there will be a file in `/migrations/000_base_my_plugin.lua` +containing the initial migrations. We'll see how this is done in a minute. + +## Adding a new migration to an existing plugin + +Sometimes it is necessary to introduce changes after a version of a plugin has already been +released. A new functionality might be needed. A database table row might need changing. + +When this happens, *you must* create a new migrations file. You *must not* of modify the +existing migration files once they are published (you can still make them more robust and +bulletproof if you want, e.g. always try to write the migrations reentrant). + +While there is no strict rule for naming your migration files, there is a convention that the +initial one is prefixed by `000`, the next one by `001`, and so on. + +Following with our previous example, if we wanted to release a new version of the plugin with +changes in the database (for example, a table was needed called `foo`) we would insert it by +adding a file called `/migrations/001_100_to_110.lua`, and referencing it on the +migrations init file like so (where `100` is the previous version of the plugin `1.0.0` and +`110` is the version to which plugin is migrated to `1.1.0`: + + +``` lua +-- `/migrations/init.lua` +return { + "000_base_my_plugin", + "001_100_to_110", +} +``` + +## Migration File syntax + +While Kong's core migrations support both Postgres and Cassandra, custom plugins +can choose to support either both of them or just one. + +A migration file is a Lua file which returns a table with the following structure: + +``` lua +-- `/migrations/000_base_my_plugin.lua` +return { + postgresql = { + up = [[ + CREATE TABLE IF NOT EXISTS "my_plugin_table" ( + "id" UUID PRIMARY KEY, + "created_at" TIMESTAMP WITHOUT TIME ZONE, + "col1" TEXT + ); + + DO $$ + BEGIN + CREATE INDEX IF NOT EXISTS "my_plugin_table_col1" + ON "my_plugin_table" ("col1"); + EXCEPTION WHEN UNDEFINED_COLUMN THEN + -- Do nothing, accept existing state + END$$; + ]], + }, + + cassandra = { + up = [[ + CREATE TABLE IF NOT EXISTS my_plugin_table ( + id uuid PRIMARY KEY, + created_at timestamp, + col1 text + ); + + CREATE INDEX IF NOT EXISTS ON my_plugin_table (col1); + ]], + } +} + +-- `/migrations/001_100_to_110.lua` +return { + postgresql = { + up = [[ + DO $$ + BEGIN + ALTER TABLE IF EXISTS ONLY "my_plugin_table" ADD "cache_key" TEXT UNIQUE; + EXCEPTION WHEN DUPLICATE_COLUMN THEN + -- Do nothing, accept existing state + END; + $$; + ]], + teardown = function(connector, helpers) + assert(connector:connect_migrations()) + assert(connector:query([[ + DO $$ + BEGIN + ALTER TABLE IF EXISTS ONLY "my_plugin_table" DROP "col1"; + EXCEPTION WHEN UNDEFINED_COLUMN THEN + -- Do nothing, accept existing state + END$$; + ]]) + end, + }, + + cassandra = { + up = [[ + ALTER TABLE my_plugin_table ADD cache_key text; + CREATE INDEX IF NOT EXISTS ON my_plugin_table (cache_key); + ]], + teardown = function(connector, helpers) + assert(connector:connect_migrations()) + assert(connector:query("ALTER TABLE my_plugin_table DROP col1")) + end, + } +} +``` + +If a plugin only supports Postgres or Cassandra, only the section for one strategy is +needed. Each strategy section has two parts, `up` and `teardown`. + +* `up` is an optional string of raw SQL/CQL statements. Those statements will be executed + when `kong migrations up` is executed. +* `teardown` is an optional Lua function, which takes a `connector` parameter. Such connector + can invoke the `query` method to execute SQL/CQL queries. Teardown is triggered by + `kong migrations finish` + +It is recommended that all the non-destructive operations, such as creation of new tables and +addition of new records is done on the `up` sections, while destructive operations (such as +removal of data, changing row types, insertion of new data) is done on the `teardown` sections. + +In both cases, it is recommended that all the SQL/CQL statements are written so that they are +as reentrant as possible. `DROP TABLE IF EXISTS` instead of `DROP TABLE`, +`CREATE INDEX IF NOT EXIST` instead of `CREATE INDEX`, etc. If a migration fails for some +reason, it is expected that the first attempt at fixing the problem will be simply +re-running the migrations. + +While Postgres does, Cassandra does not support constraints such as "NOT +NULL", "UNIQUE" or "FOREIGN KEY", but Kong provides you with such features when +you define your model's schema. Bear in mind that this schema will be the same +for both Postgres and Cassandra, hence, you might trade-off a pure SQL schema +for one that works with Cassandra too. + +**IMPORTANT**: if your `schema` uses a `unique` constraint, then Kong will +enforce it for Cassandra, but for Postgres you must set this constraint in +the migrations. + +To see a real-life example, give a look at the [Key-Auth plugin migrations](https://github.com/Kong/kong/tree/{{page.kong_version}}/kong/plugins/key-auth/migrations). + +--- + +## Defining a Schema + +The first step to using custom entities in a custom plugin is defining one +or more *schemas*. + +A schema is a Lua table which describes entities. There's structural information +like how are the different fields of the entity named and what are their types, +which is similar to the fields describing your [plugin +configuration]({{page.book.chapters.plugin-configuration}})). +Compared to plugin configuration schemas, custom entity schemas require +additional metadata (e.g. which field, or fields, constitute the entities' +primary key). + +Schemas are to be defined in a module named: + +``` +kong.plugins..daos +``` + +Meaning that there should be a file called `/daos.lua` inside your +plugin folder. The `daos.lua` file should return a table containing one or more +schemas. For example: + +```lua +-- daos.lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + -- this plugin only results in one custom DAO, named `keyauth_credentials`: + keyauth_credentials = { + name = "keyauth_credentials", -- the actual table in the database + endpoint_key = "key", + primary_key = { "id" }, + cache_key = { "key" }, + generate_admin_api = true, + admin_api_name = "key-auths", + admin_api_nested_name = "key-auth", + fields = { + { + -- a value to be inserted by the DAO itself + -- (think of serial id and the uniqueness of such required here) + id = typedefs.uuid, + }, + { + -- also interted by the DAO itself + created_at = typedefs.auto_timestamp_s, + }, + { + -- a foreign key to a consumer's id + consumer = { + type = "foreign", + reference = "consumers", + default = ngx.null, + on_delete = "cascade", + }, + }, + { + -- a unique API key + key = { + type = "string", + required = false, + unique = true, + auto = true, + }, + }, + }, + }, +} +``` + +This example `daos.lua` file introduces a single schema called `keyauth_credentials`. + +Here is a description of some top-level properties: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
namestring (required)It will be used to determine the DAO name (kong.db.[name]).
primary_keytable (required) + Field names forming the entity's primary key. + Schemas support composite keys, even if most Kong core entities currently use an UUID named + id. If you are using Cassandra and need a composite key, it should have the same + fields as the partition key. +
endpoint_keystring (optional) + The name of the field used as an alternative identifier on the Admin API. + On the example above, key is the endpoint_key. This means that a credential with + id = 123 and key = "foo" could be referenced as both + /keyauth_credentials/123 and /keyauth_credentials/foo. +
cache_keytable (optional) + Contains the name of the fields used for generating the cache_key, a string which must + unequivocally identify the entity inside Kong's cache. A unique field, like key in your example, + is usually good candidate. In other cases a combination of several fields is preferable. +
generate_admin_apiboolean (optional) + Whether to auto-generate admin api for the entity or not. By default the admin api is generated for all + daos, including custom ones. If you want to create a fully customized admin api for the dao or + want to disable auto-generation for the dao altogether, set this option to false. +
admin_api_nameboolean (optional) + When generate_admin_api is enabled the admin api auto-generator uses the name + to derive the collection urls for the auto-generated admin api. Sometimes you may want to name the + collection urls differently from the name. E.g. with DAO keyauth_credentials + we actually wanted the auto-generator to generate endpoints for this dao with alternate and more + url-friendly name key-auths, e.g. http://<KONG_ADMIN>/key-auths instead of + http://<KONG_ADMIN>/keyauth_credentials). +
admin_api_nested_nameboolean (optional) + Similar to admin_api_name the admin_api_nested_name specifies the name for + a dao that admin api auto-generator creates in nested contexts. You only need to use this parameter + if you are not happy with name or admin_api_name. Kong for legacy reasons + have urls like http://<KONG_ADMIN>/consumers/john/key-auth where key-auth + does not follow plural form of http://<KONG_ADMIN>/key-auths. admin_api_nested_name + enables you to specify different name in those cases. +
fieldstable + Each field definition is a table with a single key, which is the field's name. The table value is + a subtable containing the field's attributes, some of which will be explained below. +
+ +Many field attributes encode *validation rules*. When attempting to insert or update entities using +the DAO, these validations will be checked, and an error returned if the provided input doesn't conform +to them. + +The `typedefs` variable (obtained by requiring `kong.db.schema.typedefs`) is a table containing +a lot of useful type definitions and aliases, including `typedefs.uuid`, the most usual type for the primary key, +and `typedefs.auto_timestamp_s`, for `created_at` fields. It is used extensively when defining fields. + +Here's a non-exhaustive explanation of some of the field attributes available: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Attribute nametypeDescription
typestring + Schemas support the following scalar types: "string", "integer", "number" and + "boolean". Compound types like "array", "record", or "set" are + also supported.

+ + In additon to these values, the type attribute can also take the special "foreign" value, + which denotes a foreign relationship.

+ + Each field will need to be backed by database fields of appropriately similar types, created via migrations.

+ + type is the only required attribute for all field definitions. +
defaultany (matching with type attribute) + Specifies the value the field will have when attempting to insert it, if no value was provided. + Default values are always set via Lua, never by the underlying database. It is thus not recommended to set + any default values on fields in migrations. +
requiredboolean + When set to true on a field, an error will be thrown when attempting to insert an entity lacking a value + for said field (unless the field in question has a default value). +
uniqueboolean +

When set to true on a field, an error will be thrown when attempting to insert an entity on the database, + but another entity already has the given value on said field.

+ +

This attribute must be backed up by declaring fields as UNIQUE in migrations when using + PostgreSQL. The Cassandra strategy does a check in Lua before attempting inserts, so it doesn't require any special treatment. +

+
autoboolean + When attempting to insert an entity without providing a value for this a field where auto is set to true, +

+
    +
  • If type == "uuid", the field will take a random UUID as value.
  • +
  • If type == "string", the field will take a random string.
  • +
  • If the field name is created_at or updated_at, the field will take the current time when + inserting / updating, as appropriate.
  • +
+
referencestringRequired for fields of type foreign. The given string must be the name of an existing schema, + to which the foreign key will "point to". This means that if a schema B has a foreign key pointing to schema A, + then A needs to be loaded before B. +
on_deletestring + Optional and exclusive for fields of type foreign. It dictates what must happen + with entities linked by a foreign key when the entity being referenced is deleted. It can have three possible + values:

+ +
    +
  • "cascade": When the linked entity is deleted, all the dependent entities must also be deleted.
  • +
  • "null": When the linked entity is deleted, all the dependent entities will have their foreign key + field set to null.
  • +
  • "restrict": Attempting to delete an entity with linked entities will result in an error.
  • +
+ +

+ In Cassandra this is handled with pure Lua code, but in PostgreSQL it will be necessary to declare the references + as ON DELETE CASCADE/NULL/RESTRICT in a migration. +
+ + +To learn more about schemas, see: + +* The source code of [typedefs.lua](https://github.com/Kong/kong/blob/{{page.kong_version | replace: "x", "0"}}/kong/db/schema/typedefs.lua) + to get an idea of what's provided there by default. +* [The Core Schemas](https://github.com/Kong/kong/tree/{{page.kong_version | replace: "x", "0"}}/kong/db/schema/entities) + to see examples of some other field attributes not discussed here. +* [All the `daos.lua` files for embedded plugins](https://github.com/search?utf8=%E2%9C%93&q=repo%3Akong%2Fkong+path%3A%2Fkong%2Fplugins+filename%3Adaos.lua), + especially [the key-auth one](https://github.com/Kong/kong/blob/{{page.kong_version | replace: "x", "0"}}/kong/plugins/key-auth/daos.lua), + which was used for this guide as an example. + +--- + +## The custom DAO + +The schemas are not used directly to interact with the database. Instead, a DAO +is built for each valid schema. A DAO takes the name of the schema it wraps, and is +accessible through the `kong.db` interface. + +For the example schema above, the DAO generated would be available for plugins +via `kong.db.keyauth_credentials`. + +### Selecting an entity + +``` lua +local entity, err, err_t = kong.db.:select(primary_key) +``` + +Attempts to find an entity in the database and return it. Three things can happen: + +* The entity was found. In this case, it is returned as a regular Lua table. +* An error occurred - for example the connection with the database was lost. In that + case the first returned value will be `nil`, the second one will be a string + describing the error, and the last one will be the same error in table form. +* An error does not occur but the entity is not found. Then the function will + just return `nil`, with no error. + +Example of usage: + +``` lua +local entity, err = kong.db.keyauth_credentials:select({ + id = "c77c50d2-5947-4904-9f37-fa36182a71a9" +}) + +if err then + kong.log.err("Error when inserting keyauth credential: " .. err) + return nil +end + +if not entity then + kong.log.err("Could not find credential.") + return nil +end +``` + +### Iterating over all the entities + +``` lua +for entity, err on kong.db.:each(entities_per_page) do + if err then + ... + end + ... +end +``` + +This method efficiently iterates over all the entities in the database by making paginated +requests. The `entities_per_page` parameter, which defaults to `100`, controls how many +entities per page are returned. + +On each iteration, a new `entity` will be returned or, if there is any error, the `err` +variable will be filled up with an error. The recommended way to iterate is checking `err` first, +and otherwise assume that `entity` is present. + +Example of usage: + +``` lua +for credential, err on kong.db.keyauth_credentials:each(1000) do + if err then + kong.log.err("Error when iterating over keyauth credentials: " .. err) + return nil + end + + kong.log("id: " .. credential.id) +end +``` + +This example iterates over the credentials in pages of 1000 items, logging their ids unless +an error happens. + +### Inserting an entity + +``` lua +local entity, err, err_t = kong.db.:insert() +``` + +Inserts an entity in the database, and returns a copy of the inserted entity, or +`nil`, an error message (a string) and a table describing the error in table form. + +When the insert is successful, the returned entity contains the extra values produced by +`default` and `auto`. + +The following example uses the `keyauth_credentials` DAO to insert a credential for a given +Consumer, setting its `key` to `"secret"`. Notice the syntax for referencing foreign keys. + +``` lua +local entity, err = kong.db.keyauth_credentials:insert({ + consumer = { id = "c77c50d2-5947-4904-9f37-fa36182a71a9" }, + key = "secret", +}) + +if not entity then + kong.log.err("Error when inserting keyauth credential: " .. err) + return nil +end +``` + +The returned entity, assuming no error happened will have `auto`-filled fields, like `id` and `created_at`. + +### Updating an entity + +``` lua +local entity, err, err_t = kong.db.:update(primary_key, ) +``` + +Updates an existing entity, provided it can be found using the provided primary key and a set of values. + +The returned entity will be the entity after the update takes place, or `nil` + an error message + an error table. + +The following example modifies the `key` field of an existing credential given the credential's id: + +``` lua +local entity, err = kong.db.keyauth_credentials:update({ + { id = "2b6a2022-770a-49df-874d-11e2bf2634f5" }, + { key = "updated_secret" }, +}) + +if not entity then + kong.log.err("Error when updating keyauth credential: " .. err) + return nil +end +``` + +Notice how the syntax for specifying a primary key is similar to the one used to specify a foreign key. + +### Upserting an entity + +``` lua +local entity, err, err_t = kong.db.:upsert(primary_key, ) +``` + +`upsert` is a mixture of `insert` and `update`: + +* When the provided `primary_key` identifies an existing entity, it works like `update`. +* When the provided `primary_key` does not identify an existing entity, it works like `insert` + +Given this code: + +``` lua +local entity, err = kong.db.keyauth_credentials:upsert({ + { id = "2b6a2022-770a-49df-874d-11e2bf2634f5" }, + { consumer = { id = "a96145fb-d71e-4c88-8a5a-2c8b1947534c" } }, +}) + +if not entity then + kong.log.err("Error when upserting keyauth credential: " .. err) + return nil +end +``` + +Two things can happen: + +* If a credential with id `2b6a2022-770a-49df-874d-11e2bf2634f5` exists, + then this code will attempt to set its Consumer to the provided one. +* If the credential does not exist, then this code is attempting to create + a new credential, with the given id and Consumer. + +### Deleting an entity + +``` lua +local ok, err, err_t = kong.db.:delete(primary_key) +``` + +Attempts to delete the entity identified by `primary_key`. It returns `true` +if the entity *doesn't exist* after calling this method, or `nil` + error + +error table if an error is detected. + +Notice that calling `delete` will succeed if the entity didn't exist *before +calling it*. This is for performance reasons - we want to avoid doing a +read-before-delete if we can avoid it. If you want to do this check, you +must do it manually, by checking with `select` before invoking `delete`. + +Example: + +``` lua +local ok, err = kong.db.keyauth_credentials:delete({ + { id = "2b6a2022-770a-49df-874d-11e2bf2634f5" } +}) + +if not ok then + kong.log.err("Error when deleting keyauth credential: " .. err) + return nil +end +``` + +--- + +## Caching custom entities + +Sometimes custom entities are required on every request/response, which in turn +triggers a query on the datastore every time. This is very inefficient because +querying the datastore adds latency and slows the request/response down, and +the resulting increased load on the datastore could affect the datastore +performance itself and, in turn, other Kong nodes. + +When a custom entity is required on every request/response it is good practice +to cache it in-memory by leveraging the in-memory cache API provided by Kong. + +The next chapter will focus on caching custom entities, and invalidating them +when they change in the datastore: [Caching custom entities]({{page.book.next}}). + +--- + +Next: [Caching custom entities ›]({{page.book.next}}) + +[Admin API]: /{{page.kong_version}}/admin-api/ +[Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/2.2.x/plugin-development/custom-logic.md b/app/2.2.x/plugin-development/custom-logic.md new file mode 100644 index 000000000000..a33c57f2ac7e --- /dev/null +++ b/app/2.2.x/plugin-development/custom-logic.md @@ -0,0 +1,316 @@ +--- +title: Plugin Development - Implementing Custom Logic +book: plugin_dev +chapter: 3 +--- + +
+ Note: This chapter assumes that you are familiar with + Lua. +
+ +## Introduction + +A Kong plugin allows you to inject custom logic (in Lua) at several +entry-points in the life-cycle of a request/response or a tcp stream +connection as it is proxied by Kong. To do so, one must implement one +or several of the methods of the `base_plugin.lua` interface. Those +methods are to be implemented in a module namespaced under: +`kong.plugins..handler` + +## Module + +``` +kong.plugins..handler +``` + +## Available contexts + +The plugins interface allows you to override any of the following methods in +your `handler.lua` file to implement custom logic at various entry-points +of the execution life-cycle of Kong: + +- **[HTTP Module]** *is used for plugins written for HTTP/HTTPS requests* + +| Function name | Phase | Description +|--------------------|-------------------|------------ +| `:init_worker()` | [init_worker] | Executed upon every Nginx worker process's startup. +| `:certificate()` | [ssl_certificate] | Executed during the SSL certificate serving phase of the SSL handshake. +| `:rewrite()` | [rewrite] | Executed for every request upon its reception from a client as a rewrite phase handler. *NOTE* in this phase neither the `Service` nor the `Consumer` have been identified, hence this handler will only be executed if the plugin was configured as a global plugin! +| `:access()` | [access] | Executed for every request from a client and before it is being proxied to the upstream service. +| `:response()` | [access] | Replaces both `header_filter()` and `body_filter()`. Executed after the whole response has been received from the upstream service, but before sending any part of it to the client. +| `:header_filter()` | [header_filter] | Executed when all response headers bytes have been received from the upstream service. +| `:body_filter()` | [body_filter] | Executed for each chunk of the response body received from the upstream service. Since the response is streamed back to the client, it can exceed the buffer size and be streamed chunk by chunk. hence this method can be called multiple times if the response is large. See the [lua-nginx-module] documentation for more details. +| `:log()` | [log] | Executed when the last response byte has been sent to the client. + +**Note:** + +If a module implements the `:response()` method, Kong will automatically activate the "buffered proxy" mode, as if the [`kong.service.request.enable_buffering()` function][enable_buffering] had been called. Because of a current Nginx limitation, this doesn't work for HTTP/2 or gRPC upstreams. + +To reduce unexpected behaviour changes, Kong will abort startup if a plugin implements both `:response()` and either `:header_filter()` or `:body_filter()`. + +- **[Stream Module]** *is used for plugins written for TCP and UDP stream connections* + +| Function name | Phase | Description +|--------------------|------------------------------------------------------------------------------|------------ +| `:init_worker()` | [init_worker] | Executed upon every Nginx worker process's startup. +| `:preread()` | [preread] | Executed once for every connection. +| `:log()` | [log](https://github.com/openresty/stream-lua-nginx-module#log_by_lua_block) | Executed once for each connection after it has been closed. + +All of those functions, except `init_worker`, take one parameter which is given +by Kong upon its invocation: the configuration of your plugin. This parameter +is a Lua table, and contains values defined by your users, according to your +plugin's schema (described in the `schema.lua` module). More on plugins schemas +in the [next chapter]({{page.book.next}}). + +Note that UDP streams don't have real connections. Kong will consider all +packets with the same origin and destination host and port as a single +connection. After a configurable time without any packet, the connection is +considered closed and the `:log()` function is executed. + +[HTTP Module]: https://github.com/openresty/lua-nginx-module +[Stream Module]: https://github.com/openresty/stream-lua-nginx-module +[init_worker]: https://github.com/openresty/lua-nginx-module#init_worker_by_lua_by_lua_block +[ssl_certificate]: https://github.com/openresty/lua-nginx-module#ssl_certificate_by_lua_block +[rewrite]: https://github.com/openresty/lua-nginx-module#rewrite_by_lua_block +[access]: https://github.com/openresty/lua-nginx-module#access_by_lua_block +[header_filter]: https://github.com/openresty/lua-nginx-module#header_filter_by_lua_block +[body_filter]: https://github.com/openresty/lua-nginx-module#body_filter_by_lua_block +[log]: https://github.com/openresty/lua-nginx-module#log_by_lua_block +[preread]: https://github.com/openresty/stream-lua-nginx-module#preread_by_lua_block +[enable_buffering]: /{{page.kong_version}}/pdk/kong.service.request/#kongservicerequestenable_buffering + +--- + +## handler.lua specifications + +The `handler.lua` file must return a table implementing the functions you wish +to be executed. In favor of brevity, here is a commented example module +implementing all the available methods of both modules (please note some +of them are shared between modules, like `log`): + +
+ Note: Kong uses the + rxi/classic module to simulate + classes in Lua and ease the inheritance pattern. +
+ +```lua +-- Extending the Base Plugin handler is optional, as there is no real +-- concept of interface in Lua, but the Base Plugin handler's methods +-- can be called from your child implementation and will print logs +-- in your `error.log` file (where all logs are printed). +local BasePlugin = require "kong.plugins.base_plugin" + + +local CustomHandler = BasePlugin:extend() + + +CustomHandler.VERSION = "1.0.0" +CustomHandler.PRIORITY = 10 + + +-- Your plugin handler's constructor. If you are extending the +-- Base Plugin handler, it's only role is to instantiate itself +-- with a name. The name is your plugin name as it will be printed in the logs. +function CustomHandler:new() + CustomHandler.super.new(self, "my-custom-plugin") +end + +function CustomHandler:init_worker() + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.init_worker(self) + + -- Implement any custom logic here +end + + +function CustomHandler:preread(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.preread(self) + + -- Implement any custom logic here +end + + +function CustomHandler:certificate(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.certificate(self) + + -- Implement any custom logic here +end + +function CustomHandler:rewrite(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.rewrite(self) + + -- Implement any custom logic here +end + +function CustomHandler:access(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.access(self) + + -- Implement any custom logic here +end + +function CustomHandler:header_filter(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.header_filter(self) + + -- Implement any custom logic here +end + +function CustomHandler:body_filter(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.body_filter(self) + + -- Implement any custom logic here +end + +function CustomHandler:log(config) + -- Eventually, execute the parent implementation + -- (will log that your plugin is entering this context) + CustomHandler.super.log(self) + + -- Implement any custom logic here +end + +-- This module needs to return the created table, so that Kong +-- can execute those functions. +return CustomHandler +``` + +Of course, the logic of your plugin itself can be abstracted away in another +module, and called from your `handler` module. Many existing plugins have +already chosen this pattern when their logic is verbose, but it is purely +optional: + +```lua +local BasePlugin = require "kong.plugins.base_plugin" + +-- The actual logic is implemented in those modules +local access = require "kong.plugins.my-custom-plugin.access" +local body_filter = require "kong.plugins.my-custom-plugin.body_filter" + + +local CustomHandler = BasePlugin:extend() + + +CustomHandler.VERSION = "1.0.0" +CustomHandler.PRIORITY = 10 + + +function CustomHandler:new() + CustomHandler.super.new(self, "my-custom-plugin") +end + +function CustomHandler:access(config) + CustomHandler.super.access(self) + + -- Execute any function from the module loaded in `access`, + -- for example, `execute()` and passing it the plugin's configuration. + access.execute(config) +end + +function CustomHandler:body_filter(config) + CustomHandler.super.body_filter(self) + + -- Execute any function from the module loaded in `body_filter`, + -- for example, `execute()` and passing it the plugin's configuration. + body_filter.execute(config) +end + + +return CustomHandler +``` + +See [the source code of the Key-Auth plugin](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua) +for an example of a real-life handler code. + +--- + +## Plugin Development Kit + +Logic implemented in those phases will most likely have to interact with the +request/response objects or core components (e.g. access the cache, and +database). Kong provides a [Plugin Development Kit][pdk] (or "PDK") for such +purposes: a set of Lua functions and variables that can be used by plugins to +execute various gateway operations in a way that is guaranteed to be +forward-compatible with future releases of Kong. + +When you are trying to implement some logic that needs to interact with Kong +(e.g. retrieving request headers, producing a response from a plugin, logging +some error or debug information), you should consult the [Plugin Development +Kit Reference][pdk]. + +--- + +## Plugins execution order + +Some plugins might depend on the execution of others to perform some +operations. For example, plugins relying on the identity of the consumer have +to run **after** authentication plugins. Considering this, Kong defines +**priorities** between plugins execution to ensure that order is respected. + +Your plugin's priority can be configured via a property accepting a number in +the returned handler table: + +```lua +CustomHandler.PRIORITY = 10 +``` + +The higher the priority, the sooner your plugin's phases will be executed in +regard to other plugins' phases (such as `:access()`, `:log()`, etc.). + +The current order of execution for the bundled plugins is: + +Plugin | Priority +----------------------------|---------- +pre-function | `+inf` +zipkin | 100000 +ip-restriction | 3000 +bot-detection | 2500 +cors | 2000 +session | 1900 +kubernetes-sidecar-injector | 1006 +jwt | 1005 +oauth2 | 1004 +key-auth | 1003 +ldap-auth | 1002 +basic-auth | 1001 +hmac-auth | 1000 +request-size-limiting | 951 +acl | 950 +rate-limiting | 901 +response-ratelimiting | 900 +request-transformer | 801 +response-transformer | 800 +aws-lambda | 750 +azure-functions | 749 +prometheus | 13 +http-log | 12 +statsd | 11 +datadog | 10 +file-log | 9 +udp-log | 8 +tcp-log | 7 +loggly | 6 +syslog | 4 +request-termination | 2 +correlation-id | 1 +post-function | -1000 + +--- + +Next: [Plugin configuration ›]({{page.book.next}}) + +[lua-nginx-module]: https://github.com/openresty/lua-nginx-module +[pdk]: /{{page.kong_version}}/pdk diff --git a/app/2.2.x/plugin-development/distribution.md b/app/2.2.x/plugin-development/distribution.md new file mode 100644 index 000000000000..f6b39a49b263 --- /dev/null +++ b/app/2.2.x/plugin-development/distribution.md @@ -0,0 +1,306 @@ +--- +title: Plugin Development - (un)Installing your plugin +book: plugin_dev +chapter: 10 +--- + +## Introduction + +Custom plugins for Kong consist of Lua source files that need to be in the file +system of each of your Kong nodes. This guide will provide you with +step-by-step instructions that will make a Kong node aware of your custom +plugin(s). + +These steps should be applied to each node in your Kong cluster, to ensure the +custom plugin(s) are available on each one of them. + +## Packaging sources + +You can either use a regular packing strategy (e.g. `tar`), or use the LuaRocks +package manager to do it for you. We recommend LuaRocks as it is installed +along with Kong when using one of the official distribution packages. + +When using LuaRocks, you must create a `rockspec` file, which specifies the +package contents. For an example see the [Kong plugin +template][plugin-template], for more info about the format see the LuaRocks +[documentation on rockspecs][rockspec]. + +Pack your rock using the following command (from the plugin repo): + + # install it locally (based on the `.rockspec` in the current directory) + $ luarocks make + + # pack the installed rock + $ luarocks pack + +Assuming your plugin rockspec is called +`kong-plugin-my-plugin-0.1.0-1.rockspec`, the above would become; + + $ luarocks pack kong-plugin-my-plugin 0.1.0-1 + +The LuaRocks `pack` command has now created a `.rock` file (this is simply a +zip file containing everything needed to install the rock). + +If you do not or cannot use LuaRocks, then use `tar` to pack the +`.lua` files of which your plugin consists into a `.tar.gz` archive. You can +also include the `.rockspec` file if you do have LuaRocks on the target +systems. + +The contents of this archive should be close to the following: + + $ tree + + ├── INSTALL.txt + ├── README.md + ├── kong + │ └── plugins + │ └── + │ ├── handler.lua + │ └── schema.lua + └── -.rockspec + +[Back to top](#introduction) + +--- + +## Installing the plugin + +For a Kong node to be able to use the custom plugin, the custom plugin's Lua +sources must be installed on your host's file system. There are multiple ways +of doing so: via LuaRocks, or manually. Choose one, and jump to section 3. + +1. Via LuaRocks from the created 'rock' + + The `.rock` file is a self contained package that can be installed locally + or from a remote server. + + If the `luarocks` utility is installed in your system (this is likely the + case if you used one of the official installation packages), you can + install the 'rock' in your LuaRocks tree (a directory in which LuaRocks + installs Lua modules). + + It can be installed by doing: + + $ luarocks install + + The filename can be a local name, or any of the supported methods, eg. + `http://myrepository.lan/rocks/my-plugin-0.1.0-1.all.rock` + +2. Via LuaRocks from the source archive + + If the `luarocks` utility is installed in your system (this is likely the + case if you used one of the official installation packages), you can + install the Lua sources in your LuaRocks tree (a directory in which + LuaRocks installs Lua modules). + + You can do so by changing the current directory to the extracted archive, + where the rockspec file is: + + $ cd + + And then run the following: + + $ luarocks make + + This will install the Lua sources in `kong/plugins/` in your + system's LuaRocks tree, where all the Kong sources are already present. + +3. Manually + + A more conservative way of installing your plugin's sources is + to avoid "polluting" the LuaRocks tree, and instead, point Kong + to the directory containing them. + + This is done by tweaking the `lua_package_path` property of your Kong + configuration. Under the hood, this property is an alias to the `LUA_PATH` + variable of the Lua VM, if you are familiar with it. + + Those properties contain a semicolon-separated list of directories in + which to search for Lua sources. It should be set like so in your Kong + configuration file: + + lua_package_path = //?.lua;; + + Where: + + * `/` is the path to the directory containing the + extracted archive. It should be the location of the `kong` directory + from the archive. + * `?` is a placeholder that will be replaced by + `kong.plugins.` when Kong will try to load your plugin. Do + not change it. + * `;;` a placeholder for the "the default Lua path". Do not change it. + + Example: + + The plugin `something` being located on the file system such that the + handler file is: + + /usr/local/custom/kong/plugins//handler.lua + + The location of the `kong` directory is: `/usr/local/custom`, hence the + proper path setup would be: + + lua_package_path = /usr/local/custom/?.lua;; + + Multiple plugins: + + If you wish to install two or more custom plugins this way, you can set + the variable to something like: + + lua_package_path = /path/to/plugin1/?.lua;/path/to/plugin2/?.lua;; + + * `;` is the separator between directories. + * `;;` still means "the default Lua path". + + Note: you can also set this property via its environment variable + equivalent: `KONG_LUA_PACKAGE_PATH`. + +Reminder: regardless of which method you are using to install your plugin's +sources, you must still do so for each node in your Kong cluster. + +[Back to top](#introduction) + +--- + +## Load the plugin + +You must now add the custom plugin's name to the `plugins` list in your +Kong configuration (on each Kong node): + + plugins = bundled, + +Or, if you don't want to include the bundled plugins: + + plugins = + + +If you are using two or more custom plugins, insert commas in between, like so: + + plugins = bundled,plugin1,plugin2 + +Or + + plugins = plugin1,plugin2 + +Note: you can also set this property via its environment variable equivalent: +`KONG_PLUGINS`. + +Reminder: don't forget to update the `plugins` directive for each node +in your Kong cluster. + +Reminder: the plugin will take effect after restart kong: + + kong restart + +But, if you want to apply plugin while kong never stop, you can use this: + + kong prepare + kong reload + + +[Back to top](#introduction) + +--- + +## Verify loading the plugin + +You should now be able to start Kong without any issue. Consult your custom +plugin's instructions on how to enable/configure your plugin +on a Service, Route, or Consumer entity. + +To make sure your plugin is being loaded by Kong, you can start Kong with a +`debug` log level: + + log_level = debug + +or: + + KONG_LOG_LEVEL=debug + +Then, you should see the following log for each plugin being loaded: + + [debug] Loading plugin + + +[Back to top](#introduction) + +--- + +## Removing a plugin + +There are three steps to completely remove a plugin. + +1. Remove the plugin from your Kong Service or Route configuration. Make sure + that it is no longer applied globally nor for any Service, Route, or + consumer. This has to be done only once for the entire Kong cluster, no + restart/reload required. This step in itself will make that the plugin is + no longer in use. But it remains available and it is still possible to + re-apply the plugin. + +2. Remove the plugin from the `plugins` directive (on each Kong node). + Make sure to have completed step 1 before doing so. After this step + it will be impossible for anyone to re-apply the plugin to any Kong + Service, Route, Consumer, or even globally. This step requires to + restart/reload the Kong node to take effect. + +3. To remove the plugin thoroughly, delete the plugin-related files from + each of the Kong nodes. Make sure to have completed step 2, including + restarting/reloading Kong, before deleting the files. If you used LuaRocks + to install the plugin, you can do `luarocks remove ` to remove + it. + +[Back to top](#introduction) + +--- + +## Distributing your plugin + +The preferred way to do so is to use [LuaRocks](https://luarocks.org/), a +package manager for Lua modules. It calls such modules "rocks". **Your module +does not have to live inside the Kong repository**, but it can be if that's +how you'd like to maintain your Kong setup. + +By defining your modules (and their eventual dependencies) in a [rockspec] +file, you can install those modules on your platform via LuaRocks. You can +also upload your module on LuaRocks and make it available to everyone! + +Here is an example rockspec which would use the "builtin" build type to define +modules in Lua notation and their corresponding file: + + +For an example see the [Kong plugin template][plugin-template], for more info +about the format see the LuaRocks [documentation on rockspecs][rockspec]. + +[Back to top](#introduction) + +--- + +## Troubleshooting + +Kong can fail to start because of a misconfigured custom plugin for several +reasons: + +* "plugin is in use but not enabled" -> You configured a custom plugin from + another node, and that the plugin configuration is in the database, but the + current node you are trying to start does not have it in its `plugins` + directive. To resolve, add the plugin's name to the node's `plugins` + directive. + +* "plugin is enabled but not installed" -> The plugin's name is present in the + `plugins` directive, but that Kong is unable to load the `handler.lua` + source file from the file system. To resolve, make sure that the + [lua_package_path](/{{page.kong_version}}/configuration/#development-miscellaneous-section) + directive is properly set to load this plugin's Lua sources. + +* "no configuration schema found for plugin" -> The plugin is installed, + enabled in the `plugins` directive, but Kong is unable to load the + `schema.lua` source file from the file system. To resolve, make sure that + the `schema.lua` file is present alongside the plugin's `handler.lua` file. + +[Back to top](#introduction) + +--- + +[rockspec]: https://github.com/keplerproject/luarocks/wiki/Creating-a-rock +[plugin-template]: https://github.com/Kong/kong-plugin diff --git a/app/2.2.x/plugin-development/entities-cache.md b/app/2.2.x/plugin-development/entities-cache.md new file mode 100644 index 000000000000..50eb5cd3eb15 --- /dev/null +++ b/app/2.2.x/plugin-development/entities-cache.md @@ -0,0 +1,351 @@ +--- +title: Plugin Development - Caching Custom Entities +book: plugin_dev +chapter: 7 +--- + +## Introduction + +Your plugin may need to frequently access custom entities (explained in the +[previous chapter]({{page.book.previous}})) on every request and/or response. +Usually, loading them once and caching them in-memory dramatically improves +the performance while making sure the datastore is not stressed with an +increased load. + +Think of an api-key authentication plugin that needs to validate the api-key on +every request, thus loading the custom credential object from the datastore on +every request. When the client provides an api-key along with the request, +normally you would query the datastore to check if that key exists, and then +either block the request or retrieve the Consumer ID to identify the user. This +would happen on every request, and it would be very inefficient: + +* Querying the datastore adds latency on every request, making the request + processing slower. +* The datastore would also be affected by an increase of load, potentially + crashing or slowing down, which in turn would affect every Kong + node. + +To avoid querying the datastore every time, we can cache custom entities +in-memory on the node, so that frequent entity lookups don't trigger a +datastore query every time (only the first time), but happen in-memory, which +is much faster and reliable that querying it from the datastore (especially +under heavy load). + +## Modules + +``` +kong.plugins..daos +``` + +## Caching custom entities + +Once you have defined your custom entities, you can cache them in-memory in +your code by using the [kong.cache](/{{page.kong_version}}/pdk/#kong-cache) +module provided by the [Plugin Development Kit]: + +``` +local cache = kong.cache +``` + +There are 2 levels of cache: + +1. L1: Lua memory cache - local to an Nginx worker process. + This can hold any type of Lua value. +2. L2: Shared memory cache (SHM) - local to an Nginx node, but shared between + all the workers. This can only hold scalar values, and hence requires + (de)serialization of a more complex types such as Lua tables. + +When data is fetched from the database, it will be stored in both caches. +If the same worker process requests the data again, it will retrieve the +previously deserialized data from the Lua memory cache. If a different +worker within the same Nginx node requests that data, it will find the data +in the SHM, deserialize it (and store it in its own Lua memory cache) and +then return it. + +This module exposes the following functions: + +Function name | Description +----------------------------------------------|--------------------------- +`value, err = cache:get(key, opts?, cb, ...)` | Retrieves the value from the cache. If the cache does not have value (miss), invokes `cb` in protected mode. `cb` must return one (and only one) value that will be cached. It *can* throw errors, as those will be caught and properly logged by Kong, at the `ngx.ERR` level. This function **does** cache negative results (`nil`). As such, one must rely on its second argument `err` when checking for errors. +`ttl, err, value = cache:probe(key)` | Checks if a value is cached. If it is, returns its remaining ttl. It not, returns `nil`. The value being cached can also be a negative caching. The third return value is the value being cached itself. +`cache:invalidate_local(key)` | Evicts a value from the node's cache. +`cache:invalidate(key)` | Evicts a value from the node's cache **and** propagates the eviction events to all other nodes in the cluster. +`cache:purge()` | Evicts **all** values from the node's cache. + +Bringing back our authentication plugin example, to lookup a credential with a +specific api-key, we would write something similar to: + +```lua +-- handler.lua +local BasePlugin = require "kong.plugins.base_plugin" + + +local kong = kong + + +local function load_credential(key) + local credential, err = kong.db.keyauth_credentials:select_by_key(key) + if not credential then + return nil, err + end + return credential +end + + +local CustomHandler = BasePlugin:extend() + + +CustomHandler.VERSION = "1.0.0" +CustomHandler.PRIORITY = 1010 + + +function CustomHandler:new() + CustomHandler.super.new(self, "my-custom-plugin") +end + + +function CustomHandler:access(config) + CustomHandler.super.access(self) + + -- retrieve the apikey from the request querystring + local key = kong.request.get_query_arg("apikey") + + local credential_cache_key = kong.db.keyauth_credentials:cache_key(key) + + -- We are using cache.get to first check if the apikey has been already + -- stored into the in-memory cache. If it's not, then we lookup the datastore + -- and return the credential object. Internally cache.get will save the value + -- in-memory, and then return the credential. + local credential, err = kong.cache:get(credential_cache_key, nil, + load_credential, credential_cache_key) + if err then + kong.log.err(err) + return kong.response.exit(500, { + message = "Unexpected error" + }) + end + + if not credential then + -- no credentials in cache nor datastore + return kong.response.exit(401, { + message = "Invalid authentication credentials" + }) + end + + -- set an upstream header if the credential exists and is valid + kong.service.request.set_header("X-API-Key", credential.apikey) +end + + +return CustomHandler +``` + +Note that in the above example, we use various components from the [Plugin +Development Kit] to interact with the request, cache module, or even produce a +response from our plugin. + +Now, with the above mechanism in place, once a Consumer has made a request with +their API key, the cache will be considered warm and subsequent requests won't +result in a database query. + +The cache is used in several places in the [Key-Auth plugin handler](https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/handler.lua). +Give that file a look in order to see how an official plugin uses the cache. + +### Updating or deleting a custom entity + +Every time a cached custom entity is updated or deleted in the datastore (i.e. +using the Admin API), it creates an inconsistency between the data in the +datastore, and the data cached in the Kong nodes' memory. To avoid this +inconsistency, we need to evict the cached entity from the in-memory store and +force Kong to request it again from the datastore. We refer to this process as +cache invalidation. + +--- + +## Cache invalidation for your entities + +If you wish that your cached entities be invalidated upon a CRUD operation +rather than having to wait for them to reach their TTL, you have to follow a +few steps. This process can be automated for most entities, but manually +subscribing to some CRUD events might be required to invalidate some entities +with more complex relationships. + +### Automatic cache invalidation + +Cache invalidation can be provided out of the box for your entities if you rely +on the `cache_key` property of your entity's schema. For example, in the +following schema: + +```lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + -- this plugin only results in one custom DAO, named `keyauth_credentials`: + keyauth_credentials = { + name = "keyauth_credentials", -- the actual table in the database + endpoint_key = "key", + primary_key = { "id" }, + cache_key = { "key" }, + generate_admin_api = true, + admin_api_name = "key-auths", + admin_api_nested_name = "key-auth", + fields = { + { + -- a value to be inserted by the DAO itself + -- (think of serial id and the uniqueness of such required here) + id = typedefs.uuid, + }, + { + -- also interted by the DAO itself + created_at = typedefs.auto_timestamp_s, + }, + { + -- a foreign key to a consumer's id + consumer = { + type = "foreign", + reference = "consumers", + default = ngx.null, + on_delete = "cascade", + }, + }, + { + -- a unique API key + key = { + type = "string", + required = false, + unique = true, + auto = true, + }, + }, + }, + }, +} +``` + +We can see that we declare the cache key of this API key entity to be its +`key` attribute. We use `key` here because it has a unique constraints +applied to it. Hence, the attributes added to `cache_key` should result in +a unique combination, so that no two entities could yield the same cache key. + +Adding this value allows you to use the following function on the DAO of that +entity: + +```lua +cache_key = kong.db.:cache_key(arg1, arg2, arg3, ...) +``` + +Where the arguments must be the attributes specified in your schema's +`cache_key` property, in the order they were specified. This function then +computes a string value `cache_key` that is ensured to be unique. + +For example, if we were to generate the cache_key of an API key: + +```lua +local cache_key = kong.db.keyauth_credentials:cache_key("abcd") +``` + +This would produce a cache_key for the API key `"abcd"` (retrieved from one +of the query's arguments) that we can the use to retrieve the key from the +cache (or fetch from the database if the cache is a miss): + +```lua +local key = kong.request.get_query_arg("apikey") +local cache_key = kong.db.keyauth_credentials:cache_key(key) + +local credential, err = kong.cache:get(cache_key, nil, load_entity_key, apikey) +if err then + kong.log.err(err) + return kong.response.exit(500, { message = "Unexpected error" }) +end + +if not credential then + return kong.response.exit(401, { message = "Invalid authentication credentials" }) +end + + +-- do something with the credential +``` + +If the `cache_key` is generated like so and specified in an entity's schema, +cache invalidation will be an automatic process: every CRUD operation that +affects this API key will be make Kong generate the affected `cache_key`, and +broadcast it to all of the other nodes on the cluster so they can evict +that particular value from their cache, and fetch the fresh value from the +datastore on the next request. + +When a parent entity is receiving a CRUD operation (e.g. the Consumer owning +this API key, as per our schema's `consumer_id` attribute), Kong performs the +cache invalidation mechanism for both the parent and the child entity. + +**Note**: Be aware of the negative caching that Kong provides. In the above +example, if there is no API key in the datastore for a given key, the cache +module will store the miss just as if it was a hit. This means that a +"Create" event (one that would create an API key with this given key) is also +propagated by Kong so that all nodes that stored the miss can evict it, and +properly fetch the newly created API key from the datastore. + +See the [Clustering Guide](/{{page.kong_version}}/clustering/) to ensure +that you have properly configured your cluster for such invalidation events. + +### Manual cache invalidation + +In some cases, the `cache_key` property of an entity's schema is not flexible +enough, and one must manually invalidate its cache. Reasons for this could be +that the plugin is not defining a relationship with another entity via the +traditional `foreign = "parent_entity:parent_attribute"` syntax, or because +it is not using the `cache_key` method from its DAO, or even because it is +somehow abusing the caching mechanism. + +In those cases, you can manually setup your own subscriber to the same +invalidation channels Kong is listening to, and perform your own, custom +invalidation work. + +To listen on invalidation channels inside of Kong, implement the following in +your plugin's `init_worker` handler: + +```lua +function MyCustomHandler:init_worker() + -- listen to all CRUD operations made on Consumers + kong.worker_events.register(function(data) + + end, "crud", "consumers") + + -- or, listen to a specific CRUD operation only + kong.worker_events.register(function(data) + kong.log.inspect(data.operation) -- "update" + kong.log.inspect(data.old_entity) -- old entity table (only for "update") + kong.log.inspect(data.entity) -- new entity table + kong.log.inspect(data.schema) -- entity's schema + end, "crud", "consumers:update") +end +``` + +Once the above listeners are in place for the desired entities, you can perform +manual invalidations of any entity that your plugin has cached as you wish so. +For instance: + +```lua +kong.worker_events.register(function(data) + if data.operation == "delete" then + local cache_key = data.entity.id + kong.cache:invalidate("prefix:" .. cache_key) + end +end, "crud", "consumers") +``` + +## Extending the Admin API + +As you are probably aware, the [Admin API] is where Kong users communicate with +Kong to setup their APIs and plugins. It is likely that they also need to be +able to interact with the custom entities you implemented for your plugin (for +example, creating and deleting API keys). The way you would do this is by +extending the Admin API, which we will detail in the next chapter: +[Extending the Admin API]({{page.book.next}}). + +--- + +Next: [Extending the Admin API ›]({{page.book.next}}) + +[Admin API]: /{{page.kong_version}}/admin-api/ +[Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/2.2.x/plugin-development/file-structure.md b/app/2.2.x/plugin-development/file-structure.md new file mode 100644 index 000000000000..84f8599232c7 --- /dev/null +++ b/app/2.2.x/plugin-development/file-structure.md @@ -0,0 +1,124 @@ +--- +title: Plugin Development - File Structure +book: plugin_dev +chapter: 2 +--- + +
+ Note: This chapter assumes that you are familiar with + Lua. +
+ +## Introduction + +Consider your plugin as a set of [Lua +modules](http://www.lua.org/manual/5.1/manual.html#6.3). Each file described in +this chapter is to be considered as a separate module. Kong will detect and +load your plugin's modules if their names follow this convention: + +``` +kong.plugins.. +``` + +> Your modules of course need to be accessible through your +> [package.path](http://www.lua.org/manual/5.1/manual.html#pdf-package.path) +> variable, which can be tweaked to your needs via the +> [lua_package_path](/{{page.kong_version}}/configuration/#lua_package_path) +> configuration property. +> However, the preferred way of installing plugins is through +> [LuaRocks](https://luarocks.org/), which Kong natively integrates with. +> More on LuaRocks-installed plugins later in this guide. + +To make Kong aware that it has to look for your plugin's modules, you'll have +to add it to the +[plugins](/{{page.kong_version}}/configuration/#plugins) property in +your configuration file, which is a comma-separated list. For example: + +```yaml +plugins = bundled,my-custom-plugin # your plugin name here +``` + +Or, if you don't want to load any of the bundled plugins: + +```yaml +plugins = my-custom-plugin # your plugin name here +``` + +Now, Kong will try to load several Lua modules from the following namespace: + +``` +kong.plugins.my-custom-plugin. +``` + +Some of these modules are mandatory (e.g. `handler.lua`), and some are +optional, and will allow the plugin to implement some extra-functionalities +(e.g. `api.lua` to extend the Admin API endpoints). + +Now let's describe exactly what are the modules you can implement and what +their purpose is. + +--- + +## Basic plugin modules + +In its purest form, a plugin consists of two mandatory modules: + +``` +simple-plugin +├── handler.lua +└── schema.lua +``` + +- **[handler.lua]**: the core of your plugin. It is an interface to implement, in + which each function will be run at the desired moment in the lifecycle of a + request / connection. +- **[schema.lua]**: your plugin probably has to retain some configuration entered + by the user. This module holds the *schema* of that configuration and defines + rules on it, so that the user can only enter valid configuration values. + +--- + +## Advanced plugin modules + +Some plugins might have to integrate deeper with Kong: have their own table in +the database, expose endpoints in the Admin API, etc. Each of those can be +done by adding a new module to your plugin. Here is what the structure of a +plugin would look like if it was implementing all of the optional modules: + +``` +complete-plugin +├── api.lua +├── daos.lua +├── handler.lua +├── migrations +│   ├── init.lua +│   └── 000_base_complete_plugin.lua +└── schema.lua +``` + +Here is the complete list of possible modules to implement and a brief +description of what their purpose is. This guide will go in details to let you +master each one of them. + +| Module name | Required | Description +|:-----------------------|------------|------------ +| **[api.lua]** | No | Defines a list of endpoints to be available in the Admin API to interact with the custom entities handled by your plugin. +| **[daos.lua]** | No | Defines a list of DAOs (Database Access Objects) that are abstractions of custom entities needed by your plugin and stored in the datastore. +| **[handler.lua]** | Yes | An interface to implement. Each function is to be run by Kong at the desired moment in the lifecycle of a request / connection. +| **[migrations/*.lua]** | No | The database migrations (e.g. creation of tables). Migrations are only necessary when your plugin has to store custom entities in the database and interact with them through one of the DAOs defined by [daos.lua]. +| **[schema.lua]** | Yes | Holds the schema of your plugin's configuration, so that the user can only enter valid configuration values. + +The [Key-Auth plugin] is an example of plugin with this file structure. +See [its source code] for more details. + +--- + +Next: [Write custom logic ›]({{page.book.next}}) + +[api.lua]: {{page.book.chapters.admin-api}} +[daos.lua]: {{page.book.chapters.custom-entities}} +[handler.lua]: {{page.book.chapters.custom-logic}} +[schema.lua]: {{page.book.chapters.plugin-configuration}} +[migrations/*.lua]: {{page.book.chapters.custom-entities}} +[Key-Auth plugin]: /hub/kong-inc/key-auth/ +[its source code]: https://github.com/Kong/kong/tree/master/kong/plugins/key-auth diff --git a/app/2.2.x/plugin-development/index.md b/app/2.2.x/plugin-development/index.md new file mode 100644 index 000000000000..a317d734fffd --- /dev/null +++ b/app/2.2.x/plugin-development/index.md @@ -0,0 +1,37 @@ +--- +title: Plugin Development - Introduction +book: plugin_dev +chapter: 1 +--- + +# What are plugins and how do they integrate with Kong? + +Before going further, it is necessary to briefly explain how Kong is built, +especially how it integrates with Nginx and what Lua has to do with it. + +[lua-nginx-module] enables Lua scripting capabilities in Nginx. Instead of +compiling Nginx with this module, Kong is distributed along with +[OpenResty](https://openresty.org/), which already includes lua-nginx-module. +OpenResty is *not* a fork of Nginx, but a bundle of modules extending its +capabilities. + +Hence, Kong is a Lua application designed to load and execute Lua modules +(which we more commonly refer to as "*plugins*") and provides an entire +development environment for them, including an SDK, database abstractions, +migrations, and more. + +Plugins consist of Lua modules interacting with the request/response objects or +streams via the **Plugin Development Kit** (or "PDK") to implement arbitrary logic. +The PDK is a set of Lua functions that a plugin can use to facilitate interactions +between plugins and the core (or other components) of Kong. + +This guide will explore in detail the structure of plugins, what they can +extend, and how to distribute and install them. For a complete reference of the +PDK, see the [Plugin Development Kit] reference. + +--- + +Next: [File structure of a plugin ›]({{page.book.next}}) + +[lua-nginx-module]: https://github.com/openresty/lua-nginx-module +[Plugin Development Kit]: /{{page.kong_version}}/pdk diff --git a/app/2.2.x/plugin-development/plugin-configuration.md b/app/2.2.x/plugin-development/plugin-configuration.md new file mode 100644 index 000000000000..b206ffcb3519 --- /dev/null +++ b/app/2.2.x/plugin-development/plugin-configuration.md @@ -0,0 +1,409 @@ +--- +title: Plugin Development - Plugin Configuration +book: plugin_dev +chapter: 4 +--- + +## Introduction + +Most of the time, it makes sense for your plugin to be configurable to answer +all of your users' needs. Your plugin's configuration is stored in the +datastore for Kong to retrieve it and pass it to your +[handler.lua]({{page.book.chapters.custom-logic}}) methods when the plugin is +being executed. + +The configuration consists of a Lua table in Kong that we call a **schema**. It +contains key/value properties that the user will set when enabling the plugin +through the [Admin API]. Kong provides you with a way of validating the user's +configuration for your plugin. + +Your plugin's configuration is being verified against your schema when a user +issues a request to the [Admin API] to enable or update a plugin on a given +Service, Route and/or Consumer. + +For example, a user performs the following request: + +```bash +$ curl -X POST http://kong:8001/services//plugins \ + -d "name=my-custom-plugin" \ + -d "config.foo=bar" +``` + +If all properties of the `config` object are valid according to your schema, +then the API would return `201 Created` and the plugin would be stored in the +database along with its configuration: +```lua +{ + foo = "bar" +} + ``` + +If the configuration is not valid, the Admin API would return `400 Bad Request` +and the appropriate error messages. + +## Module + +``` +kong.plugins..schema +``` + +## schema.lua specifications + +This module is to return a Lua table with properties that will define how your +plugins can later be configured by users. Available properties are: + +| Property name | Lua type | Description +|-----------------|------------|------------ +| `name` | `string` | Name of the plugin, e.g. `key-auth`. +| `fields` | `table` | Array of field definitions. +| `entity_checks` | `function` | Array of conditional entity level validation checks. + + +All the plugins inherit some default fields which are: + +| Field name | Lua type | Description +|-----------------|------------|------------ +| `id` | `string` | Auto-generated plugin id. +| `name` | `string` | Name of the plugin, e.g. `key-auth`. +| `created_at` | `number` | Creation time of the plugin configuration (seconds from epoch). +| `route` | `table` | Route to which plugin is bound, if any. +| `service` | `table` | Service to which plugin is bound, if any. +| `consumer` | `table` | Consumer to which plugin is bound when possible, if any. +| `protocols` | `table` | The plugin will run on specified protocol(s). +| `enabled` | `boolean` | Whether or not the plugin is enabled. +| `tags` | `table` | The tags for the plugin. + +In most of the cases you can ignore most of those and use the defaults. Or let the user +specify value when enabling a plugin. + +Here is an example of a potential `schema.lua` file (with some overrides applied): + +```lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + name = "", + fields = { + { + -- this plugin will only be applied to Services or Routes + consumer = typedefs.no_consumer + }, + { + -- this plugin will only run within Nginx HTTP module + protocols = typedefs.protocols_http + }, + { + config = { + type = "record", + fields = { + -- Describe your plugin's configuration's schema here. + }, + }, + }, + }, + entity_checks = { + -- Describe your plugin's entity validation rules + }, +} +``` + +## Describing your configuration schema + +The `config.fields` property of your `schema.lua` file describes the schema of your +plugin's configuration. It is a flexible array of field definitions where each field +is a valid configuration property for your plugin, describing the rules for that +property. For example: + +```lua +{ + name = "", + fields = { + config = { + type = "record", + fields = { + { + some_string = { + type = "string", + required = false, + }, + }, + { + some_boolean = { + type = "boolean", + default = false, + }, + }, + { + some_array = { + type = "array", + elements = { + type = "string", + one_of = { + "GET", + "POST", + "PUT", + "DELETE", + }, + }, + }, + }, + }, + }, + }, +} +``` + +Here is the list of some common (not all) accepted rules for a property (see the fields table above for examples): + +| Rule | Description +|--------------------|---------------------------- +| `type` | The type of a property. +| `required` | Whether or not the property is required +| `default` | The default value for the property when not specified +| `elements` | Field definition of `array` or `set` elements. +| `keys` | Field definition of `map` keys. +| `values` | Field definition of `map` values. +| `fields` | Field definition(s) of `record` fields. + +There are many more, but the above are commonly used. + +You can also add field validators, to mention a few: + +| Rule | Description +|--------------------|---------------------------- +| `between` | Checks that the input number is between allowed values. +| `eq` | Checks the equality of the input to allowed value. +| `ne` | Checks the inequality of the input to allowed value. +| `gt` | Checks that the number is greater than given value. +| `len_eq` | Checks that the input string length is equal to the given value. +| `len_min` | Checks that the input string length is at least the given value. +| `len_max` | Checks that the input string length is at most the given value. +| `match` | Checks that the input string matches the given Lua pattern. +| `not_match` | Checks that the input string doesn't match the given Lua pattern. +| `match_all` | Checks that the input string matches all the given Lua patterns. +| `match_none` | Checks that the input string doesn't match any of the given Lua patterns. +| `match_any` | Checks that the input string matches any of the given Lua patterns. +| `starts_with` | Checks that the input string starts with a given value. +| `one_of` | Checks that the input string is one of the accepted values. +| `contains` | Checks that the input array contains the given value. +| `is_regex` | Checks that the input string is a valid regex pattern. +| `custom_validator` | A custom validation function written in Lua. + +There are some additional validators, but you get a good idea how you can specify validation +rules on fields from the above table. + +--- + +### Examples + +This `schema.lua` file is for the [key-auth](/hub/kong-inc/key-auth/) plugin: + +```lua +-- schema.lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + name = "key-auth", + fields = { + { + consumer = typedefs.no_consumer + }, + { + protocols = typedefs.protocols_http + }, + { + config = { + type = "record", + fields = { + { + key_names = { + type = "array", + required = true, + elements = typedefs.header_name, + default = { + "apikey", + }, + }, + }, + { + hide_credentials = { + type = "boolean", + default = false, + }, + }, + { + anonymous = { + type = "string", + uuid = true, + legacy = true, + }, + }, + { + key_in_body = { + type = "boolean", + default = false, + }, + }, + { + run_on_preflight = { + type = "boolean", + default = true, + }, + }, + }, + }, + }, + }, +} +``` + +Hence, when implementing the `access()` function of your plugin in +[handler.lua]({{page.book.chapters.custom-logic}}) and given that the user +enabled the plugin with the default values, you'd have access to: + +```lua +-- handler.lua +local BasePlugin = require "kong.plugins.base_plugin" + + +local kong = kong + + +local CustomHandler = BasePlugin:extend() + + +CustomHandler.VERSION = "1.0.0" +CustomHandler.PRIORITY = 10 + + +function CustomHandler:new() + CustomHandler.super.new(self, "my-custom-plugin") +end + + +function CustomHandler:access(config) + CustomHandler.super.access(self) + + kong.log.inspect(config.key_names) -- { "apikey" } + kong.log.inspect(config.hide_credentials) -- false +end + + +return CustomHandler +``` + +Note that the above example uses the +[kong.log.inspect](/{{page.kong_version}}/pdk/kong.log/#kong_log_inspect) +function of the [Plugin Development Kit] to print out those values to the Kong +logs. + +--- + +A more complex example, which could be used for an eventual logging plugin: + +```lua +-- schema.lua +local typedefs = require "kong.db.schema.typedefs" + + +return { + name = "my-custom-plugin", + fields = { + { + config = { + type = "record", + fields = { + { + environment = { + type = "string", + required = true, + one_of = { + "production", + "development", + }, + }, + }, + { + server = { + type = "record", + fields = { + { + host = typedefs.host { + default = "example.com", + }, + }, + { + port = { + type = "number", + default = 80, + between = { + 0, + 65534 + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, +} +``` + +Such a configuration will allow a user to post the configuration to your plugin +as follows: + +```bash +$ curl -X POST http://kong:8001/services//plugins \ + -d "name=my-custom-plugin" \ + -d "config.environment=development" \ + -d "config.server.host=http://localhost" +``` + +And the following will be available in +[handler.lua]({{page.book.chapters.custom-logic}}): + +```lua +-- handler.lua +local BasePlugin = require "kong.plugins.base_plugin" + + +local kong = kong + + +local CustomHandler = BasePlugin:extend() + + +CustomHandler.VERSION = "1.0.0" +CustomHandler.PRIORITY = 10 + + +function CustomHandler:new() + CustomHandler.super.new(self, "my-custom-plugin") +end + +function CustomHandler:access(config) + CustomHandler.super.access(self) + + kong.log.inspect(config.environment) -- "development" + kong.log.inspect(config.server.host) -- "http://localhost" + kong.log.inspect(config.server.port) -- 80 +end + + +return CustomHandler +``` + +You can also see a real-world example of schema in [the Key-Auth plugin source code]. + +--- + +Next: [Accessing the Datastore ›]({{page.book.next}}) + +[Admin API]: /{{page.kong_version}}/admin-api +[Plugin Development Kit]: /{{page.kong_version}}/pdk +[the Key-Auth plugin source code]: https://github.com/Kong/kong/blob/master/kong/plugins/key-auth/schema.lua diff --git a/app/2.2.x/plugin-development/tests.md b/app/2.2.x/plugin-development/tests.md new file mode 100644 index 000000000000..c94392339c74 --- /dev/null +++ b/app/2.2.x/plugin-development/tests.md @@ -0,0 +1,108 @@ +--- +title: Plugin Development - Writing tests +book: plugin_dev +chapter: 9 +toc: false +--- + +## Introduction + +If you are serious about your plugins, you probably want to write tests for it. +Unit testing Lua is easy, and [many testing +frameworks](http://lua-users.org/wiki/UnitTesting) are available. However, you +might also want to write integration tests. Again, Kong has your back. + +## Write integration tests + +The preferred testing framework for Kong is +[busted](http://olivinelabs.com/busted/) running with the +[resty-cli](https://github.com/openresty/resty-cli) interpreter, though you are +free to use another one if you wish. In the Kong repository, the busted +executable can be found at `bin/busted`. + +Kong provides you with a helper to start and stop it from Lua in your test +suite: `spec.helpers`. This helper also provides you with ways to insert +fixtures in your datastore before running your tests, as well as dropping it, +and various other helpers. + +If you are writing your plugin in your own repository, you will need to copy +the following files until the Kong testing framework is released: + +- `bin/busted`: the busted executable running with the resty-cli interpreter +- `spec/helpers.lua`: helper functions to start/stop Kong from busted +- `spec/kong_tests.conf`: a configuration file for your running your test Kong instances with the helpers module + +Assuming that the `spec.helpers` module is available in your `LUA_PATH`, you +can use the following Lua code in busted to start and stop Kong: + +```lua +local helpers = require "spec.helpers" + +for _, strategy in helpers.each_strategy() do + describe("my plugin", function() + + local bp = helpers.get_db_utils(strategy) + + setup(function() + local service = bp.services:insert { + name = "test-service", + host = "httpbin.org" + } + + bp.routes:insert({ + hosts = { "test.com" }, + service = { id = service.id } + }) + + -- start Kong with your testing Kong configuration (defined in "spec.helpers") + assert(helpers.start_kong( { plugins = "bundled,my-plugin" })) + + admin_client = helpers.admin_client() + end) + + teardown(function() + if admin_client then + admin_client:close() + end + + helpers.stop_kong() + end) + + before_each(function() + proxy_client = helpers.proxy_client() + end) + + after_each(function() + if proxy_client then + proxy_client:close() + end + end) + + describe("thing", function() + it("should do thing", function() + -- send requests through Kong + local res = proxy_client:get("/get", { + headers = { + ["Host"] = "test.com" + } + }) + + local body = assert.res_status(200, res) + + -- body is a string containing the response + end) + end) + end) +end +``` + +> Reminder: With the test Kong configuration file, Kong is running with +its proxy listening on port 9000 (HTTP), 9443 (HTTPS) +and Admin API on port 9001. + +If you want to see a real-world example, give a look at the +[Key-Auth plugin specs](https://github.com/Kong/kong/tree/master/spec/03-plugins/09-key-auth) + +--- + +Next: [Distribute your plugin ›]({{page.book.next}}) diff --git a/app/2.2.x/proxy.md b/app/2.2.x/proxy.md new file mode 100644 index 000000000000..a38c80537949 --- /dev/null +++ b/app/2.2.x/proxy.md @@ -0,0 +1,1376 @@ +--- +title: Proxy Reference +skip_read_time: true +--- + +## Introduction + +In this document we will cover Kong's **proxying capabilities** by explaining +its routing capabilities and internal workings in details. + +Kong exposes several interfaces which can be tweaked by three configuration +properties: + +- `proxy_listen`, which defines a list of addresses/ports on which Kong will + accept **public HTTP (gRPC, WebSocket, etc) traffic** from clients and proxy + it to your upstream services (`8000` by default). +- `admin_listen`, which also defines a list of addresses and ports, but those + should be restricted to only be accessed by administrators, as they expose + Kong's configuration capabilities: the **Admin API** (`8001` by default). +- `stream_listen`, which is similar to `proxy_listen` but for Layer 4 (TCP, TLS) + generic proxy. This is turned off by default. + +
+

Note: Starting with 1.0.0, the API entity has been removed. +This document will cover proxying with the new Routes and +Services entities.

+

See an older version of this document if you are using 0.12 or +below.

+
+ +## Terminology + +- `client`: Refers to the *downstream* client making requests to Kong's + proxy port. +- `upstream service`: Refers to your own API/service sitting behind Kong, to + which client requests/connections are forwarded. +- `Service`: Service entities, as the name implies, are abstractions of each of + your own upstream services. Examples of Services would be a data + transformation microservice, a billing API, etc. +- `Route`: This refers to the Kong Routes entity. Routes are entrypoints into + Kong, and defining rules for a request to be matched, and routed to a given + Service. +- `Plugin`: This refers to Kong "plugins", which are pieces of business logic + that run in the proxying lifecycle. Plugins can be configured through the + Admin API - either globally (all incoming traffic) or on specific Routes + and Services. + +[Back to top](#introduction) + +## Overview + +From a high-level perspective, Kong listens for HTTP traffic on its configured +proxy port(s) (`8000` and `8443` by default) and L4 traffic on explicitly configured +`stream_listen` ports. Kong will evaluate any incoming +HTTP request or L4 connection against the Routes you have configured and try to find a matching +one. If a given request matches the rules of a specific Route, Kong will +process proxying the request. + +Because each Route may be linked to a Service, Kong will run the plugins you +have configured on your Route and its associated Service, and then proxy the +request upstream. You can manage Routes via Kong's Admin API. Routes have +special attributes that are used for routing - matching incoming HTTP requests. +Routing attributes differ by subsystem (HTTP/HTTPS, gRPC/gRPCS, and TCP/TLS). + +Subsystems and routing attributes: +- `http`: `methods`, `hosts`, `headers`, `paths` (and `snis`, if `https`) +- `tcp`: `sources`, `destinations` (and `snis`, if `tls`) +- `grpc`: `hosts`, `headers`, `paths` (and `snis`, if `grpcs`) + +If one attempts to configure a Route with a routing attribute it doesn't support +(e.g., an `http` route with `sources` or `destinations` fields), an error message +will be reported: + +``` +HTTP/1.1 400 Bad Request +Content-Type: application/json +Server: kong/ + +{ + "code": 2, + "fields": { + "sources": "cannot set 'sources' when 'protocols' is 'http' or 'https'" + }, + "message": "schema violation (sources: cannot set 'sources' when 'protocols' is 'http' or 'https')", + "name": "schema violation" +} +``` + +If Kong receives a request that it cannot match against any of the configured +Routes (or if no Routes are configured), it will respond with: + +```http +HTTP/1.1 404 Not Found +Content-Type: application/json +Server: kong/ + +{ + "message": "no route and no Service found with those values" +} +``` + +[Back to top](#introduction) + +## Reminder: How to configure a Service + +The [Configuring a Service][configuring-a-service] quickstart guide explains +how Kong is configured via the [Admin API][API]. + +Adding a Service to Kong is done by sending an HTTP request to the Admin API: + +```bash +$ curl -i -X POST http://localhost:8001/services/ \ + -d 'name=foo-service' \ + -d 'url=http://foo-service.com' +HTTP/1.1 201 Created +... + +{ + "connect_timeout": 60000, + "created_at": 1515537771, + "host": "foo-service.com", + "id": "d54da06c-d69f-4910-8896-915c63c270cd", + "name": "foo-service", + "path": "/", + "port": 80, + "protocol": "http", + "read_timeout": 60000, + "retries": 5, + "updated_at": 1515537771, + "write_timeout": 60000 +} +``` + +This request instructs Kong to register a Service named "foo-service", which +points to `http://foo-service.com` (your upstream). + +**Note:** the `url` argument is a shorthand argument to populate the +`protocol`, `host`, `port`, and `path` attributes at once. + +Now, in order to send traffic to this Service through Kong, we need to specify +a Route, which acts as an entrypoint to Kong: + +```bash +$ curl -i -X POST http://localhost:8001/routes/ \ + -d 'hosts[]=example.com' \ + -d 'paths[]=/foo' \ + -d 'service.id=d54da06c-d69f-4910-8896-915c63c270cd' +HTTP/1.1 201 Created +... + +{ + "created_at": 1515539858, + "hosts": [ + "example.com" + ], + "id": "ee794195-6783-4056-a5cc-a7e0fde88c81", + "methods": null, + "paths": [ + "/foo" + ], + "preserve_host": false, + "priority": 0, + "protocols": [ + "http", + "https" + ], + "service": { + "id": "d54da06c-d69f-4910-8896-915c63c270cd" + }, + "strip_path": true, + "updated_at": 1515539858 +} +``` + +We have now configured a Route to match incoming requests matching the given +`hosts` and `paths`, and forward them to the `foo-service` we configured, thus +proxying this traffic to `http://foo-service.com`. + +Kong is a transparent proxy, and it will by default forward the request to your +upstream service untouched, with the exception of various headers such as +`Connection`, `Date`, and others as required by the HTTP specifications. + +[Back to top](#introduction) + +## Routes and matching capabilities + +Let's now discuss how Kong matches a request against the configured routing +attributes. + +Kong supports native proxying of HTTP/HTTPS, TCL/TLS, and GRPC/GRPCS protocols; +as mentioned earlier, each of these protocols accept a different set of routing +attributes: +- `http`: `methods`, `hosts`, `headers`, `paths` (and `snis`, if `https`) +- `tcp`: `sources`, `destinations` (and `snis`, if `tls`) +- `grpc`: `hosts`, `headers`, `paths` (and `snis`, if `grpcs`) + +Note that all three of these fields are **optional**, but at least **one of them** +must be specified. + +For a request to match a Route: + +- The request **must** include **all** of the configured fields +- The values of the fields in the request **must** match at least one of the + configured values (While the field configurations accepts one or more values, + a request needs only one of the values to be considered a match) + +Let's go through a few examples. Consider a Route configured like this: + +```json +{ + "hosts": ["example.com", "foo-service.com"], + "paths": ["/foo", "/bar"], + "methods": ["GET"] +} +``` + +Some of the possible requests matching this Route would look like: + +```http +GET /foo HTTP/1.1 +Host: example.com +``` + +```http +GET /bar HTTP/1.1 +Host: foo-service.com +``` + +```http +GET /foo/hello/world HTTP/1.1 +Host: example.com +``` + +All three of these requests satisfy all the conditions set in the Route +definition. + +However, the following requests would **not** match the configured conditions: + +```http +GET / HTTP/1.1 +Host: example.com +``` + +```http +POST /foo HTTP/1.1 +Host: example.com +``` + +```http +GET /foo HTTP/1.1 +Host: foo.com +``` + +All three of these requests satisfy only two of configured conditions. The +first request's path is not a match for any of the configured `paths`, same for +the second request's HTTP method, and the third request's Host header. + +Now that we understand how the routing properties work together, let's explore +each property individually. + +[Back to top](#introduction) + +### Request Header + +Since 1.3, Kong supports routing by arbitrary HTTP headers. A special case of this +feature is routing by the Host header, which is described below. + +Routing a request based on its Host header is the most straightforward way to +proxy traffic through Kong, especially since this is the intended usage of the +HTTP Host header. Kong makes it easy to do via the `hosts` field of the Route +entity. + +`hosts` accepts multiple values, which must be comma-separated when specifying +them via the Admin API, and is represented in a JSON payload: + +```bash +$ curl -i -X POST http://localhost:8001/routes/ \ + -H 'Content-Type: application/json' \ + -d '{"hosts":["example.com", "foo-service.com"]}' +HTTP/1.1 201 Created +... +``` + +But since the Admin API also supports form-urlencoded content types, you +can specify an array via the `[]` notation: + +```bash +$ curl -i -X POST http://localhost:8001/routes/ \ + -d 'hosts[]=example.com' \ + -d 'hosts[]=foo-service.com' +HTTP/1.1 201 Created +... +``` + +To satisfy the `hosts` condition of this Route, any incoming request from a +client must now have its Host header set to one of: + +``` +Host: example.com +``` + +or: + +``` +Host: foo-service.com +``` + +Similarly, any other header can be used for routing: + +``` +$ curl -i -X POST http://localhost:8001/routes/ \ + -d 'headers.region=north' +HTTP/1.1 201 Created +``` + +Incoming requests containing a `Region` header set to `North` will be routed to +said Route. + +``` +Region: North +``` + +[Back to top](#introduction) + +#### Using wildcard hostnames + +To provide flexibility, Kong allows you to specify hostnames with wildcards in +the `hosts` field. Wildcard hostnames allow any matching Host header to satisfy +the condition, and thus match a given Route. + +Wildcard hostnames **must** contain **only one** asterisk at the leftmost +**or** rightmost label of the domain. Examples: + +- `*.example.com` would allow Host values such as `a.example.com` and + `x.y.example.com` to match. +- `example.*` would allow Host values such as `example.com` and `example.org` + to match. + +A complete example would look like this: + +```json +{ + "hosts": ["*.example.com", "service.com"] +} +``` + +Which would allow the following requests to match this Route: + +```http +GET / HTTP/1.1 +Host: an.example.com +``` + +```http +GET / HTTP/1.1 +Host: service.com +``` + +[Back to top](#introduction) + +#### The `preserve_host` property + +When proxying, Kong's default behavior is to set the upstream request's Host +header to the hostname specified in the Service's `host`. The +`preserve_host` field accepts a boolean flag instructing Kong not to do so. + +For example, when the `preserve_host` property is not changed and a Route is +configured like so: + +```json +{ + "hosts": ["service.com"], + "service": { + "id": "..." + } +} +``` + +A possible request from a client to Kong could be: + +```http +GET / HTTP/1.1 +Host: service.com +``` + +Kong would extract the Host header value from the Service's `host` property, , +and would send the following upstream request: + +```http +GET / HTTP/1.1 +Host: +``` + +However, by explicitly configuring a Route with `preserve_host=true`: + +```json +{ + "hosts": ["service.com"], + "preserve_host": true, + "service": { + "id": "..." + } +} +``` + +And assuming the same request from the client: + +```http +GET / HTTP/1.1 +Host: service.com +``` + +Kong would preserve the Host on the client request and would send the following +upstream request instead: + +```http +GET / HTTP/1.1 +Host: service.com +``` + +[Back to top](#introduction) + +### Request headers (except Host) + +Since Kong 1.3.0, it is possible to route request by other headers besides `Host`. + +To do this, use the `headers` property in your Route: + +```json +{ + "headers": { "version": ["v1", "v2"] }, + "service": { + "id": "..." + } +} +``` + +Given a request with a header such as: + +```http +GET / HTTP/1.1 +version: v1 +``` + +This request will be routed through to the Service. The same will happen with this one: + +```http +GET / HTTP/1.1 +version: v2 +``` + +But this request will not be routed to the Service: + +```http +GET / HTTP/1.1 +version: v3 +``` + +**Note**: The `headers` keys are a logical `AND` and their values a logical `OR`. + +[Back to top](#introduction) + +### Request path + +Another way for a Route to be matched is via request paths. To satisfy this +routing condition, a client request's path **must** be prefixed with one of the +values of the `paths` attribute. + +For example, with a Route configured like so: + +```json +{ + "paths": ["/service", "/hello/world"] +} +``` + +The following requests would be matched: + +```http +GET /service HTTP/1.1 +Host: example.com +``` + +```http +GET /service/resource?param=value HTTP/1.1 +Host: example.com +``` + +```http +GET /hello/world/resource HTTP/1.1 +Host: anything.com +``` + +For each of these requests, Kong detects that their URL path is prefixed with +one of the Routes's `paths` values. By default, Kong would then proxy the +request upstream without changing the URL path. + +When proxying with path prefixes, **the longest paths get evaluated first**. +This allow you to define two Routes with two paths: `/service` and +`/service/resource`, and ensure that the former does not "shadow" the latter. + +[Back to top](#introduction) + +#### Using regexes in paths + +Kong supports regular expression pattern matching for an Route's `paths` field +via [PCRE](http://pcre.org/) (Perl Compatible Regular Expression). You can +assign paths as both prefixes and regexes to a Route at the same time. + +For example, if we consider the following Route: + +```json +{ + "paths": ["/users/\d+/profile", "/following"] +} +``` + +The following requests would be matched by this Route: + +```http +GET /following HTTP/1.1 +Host: ... +``` + +```http +GET /users/123/profile HTTP/1.1 +Host: ... +``` + +The provided regexes are evaluated with the `a` PCRE flag (`PCRE_ANCHORED`), +meaning that they will be constrained to match at the first matching point +in the path (the root `/` character). + +[Back to top](#introduction) + +##### Evaluation order + +As previously mentioned, Kong evaluates prefix paths by length: the longest +prefix paths are evaluated first. However, Kong will evaluate regex paths based +on the `regex_priority` attribute of Routes from highest priority to lowest. +Regex paths are furthermore evaluated before prefix paths. + +Consider the following Routes: + +```json +[ + { + "paths": ["/status/\d+"], + "regex_priority": 0 + }, + { + "paths": ["/version/\d+/status/\d+"], + "regex_priority": 6 + }, + { + "paths": ["/version"], + }, + { + "paths": ["/version/any/"], + } +] +``` + +In this scenario, Kong will evaluate incoming requests against the following +defined URIs, in this order: + +1. `/version/\d+/status/\d+` +2. `/status/\d+` +3. `/version/any/` +4. `/version` + +Take care to avoid writing regex rules that are overly broad and may consume +traffic intended for a prefix rule. Adding a rule with the path `/version/.*` to +the ruleset above would likely consume some traffic intended for the `/version` +prefix path. If you see unexpected behavior, sending `X-Kong-Debug: 1` in your +request headers will indicate the matched Route ID in the response headers for +troubleshooting purposes. + +As usual, a request must still match a Route's `hosts` and `methods` properties +as well, and Kong will traverse your Routes until it finds one that [matches +the most rules](#matching-priorities). + +[Back to top](#introduction) + +##### Capturing groups + +Capturing groups are also supported, and the matched group will be extracted +from the path and available for plugins consumption. If we consider the +following regex: + +``` +/version/(?\d+)/users/(?\S+) +``` + +And the following request path: + +``` +/version/1/users/john +``` + +Kong will consider the request path a match, and if the overall Route is +matched (considering other routing attributes), the extracted capturing groups +will be available from the plugins in the `ngx.ctx` variable: + +```lua +local router_matches = ngx.ctx.router_matches + +-- router_matches.uri_captures is: +-- { "1", "john", version = "1", user = "john" } +``` + +[Back to top](#introduction) + +##### Escaping special characters + +Next, it is worth noting that characters found in regexes are often +reserved characters according to +[RFC 3986](https://tools.ietf.org/html/rfc3986) and as such, +should be percent-encoded. **When configuring Routes with regex paths via the +Admin API, be sure to URL encode your payload if necessary**. For example, +with `curl` and using an `application/x-www-form-urlencoded` MIME type: + +```bash +$ curl -i -X POST http://localhost:8001/routes \ + --data-urlencode 'uris[]=/status/\d+' +HTTP/1.1 201 Created +... +``` + +Note that `curl` does not automatically URL encode your payload, and note the +usage of `--data-urlencode`, which prevents the `+` character to be URL decoded +and interpreted as a space ` ` by Kong's Admin API. + +[Back to top](#introduction) + +#### The `strip_path` property + +It may be desirable to specify a path prefix to match a Route, but not +include it in the upstream request. To do so, use the `strip_path` boolean +property by configuring a Route like so: + +```json +{ + "paths": ["/service"], + "strip_path": true, + "service": { + "id": "..." + } +} +``` + +Enabling this flag instructs Kong that when matching this Route, and proceeding +with the proxying to a Service, it should **not** include the matched part of +the URL path in the upstream request's URL. For example, the following +client's request to the above Route: + +```http +GET /service/path/to/resource HTTP/1.1 +Host: ... +``` + +Will cause Kong to send the following upstream request: + +```http +GET /path/to/resource HTTP/1.1 +Host: ... +``` + +The same way, if a regex path is defined on a Route that has `strip_path` +enabled, the entirety of the request URL matching sequence will be stripped. +Example: + +```json +{ + "paths": ["/version/\d+/service"], + "strip_path": true, + "service": { + "id": "..." + } +} +``` + +The following HTTP request matching the provided regex path: + +```http +GET /version/1/service/path/to/resource HTTP/1.1 +Host: ... +``` + +Will be proxied upstream by Kong as: + +```http +GET /path/to/resource HTTP/1.1 +Host: ... +``` + +[Back to top](#introduction) + +### Request HTTP method + +The `methods` field allows matching the requests depending on their HTTP +method. It accepts multiple values. Its default value is empty (the HTTP +method is not used for routing). + +The following Route allows routing via `GET` and `HEAD`: + +```json +{ + "methods": ["GET", "HEAD"], + "service": { + "id": "..." + } +} +``` + +Such a Route would be matched with the following requests: + +```http +GET / HTTP/1.1 +Host: ... +``` + +```http +HEAD /resource HTTP/1.1 +Host: ... +``` + +But it would not match a `POST` or `DELETE` request. This allows for much more +granularity when configuring plugins on Routes. For example, one could imagine +two Routes pointing to the same service: one with unlimited unauthenticated +`GET` requests, and a second one allowing only authenticated and rate-limited +`POST` requests (by applying the authentication and rate limiting plugins to +such requests). + +[Back to top](#introduction) + +### Request Source + +
+ **Note:** This section only applies to TCP and TLS routes. +
+ +The `sources` routing attribute allows +matching a route by a list of incoming connection IP and/or port sources. + +The following Route allows routing via a list of source IP/ports: + +```json +{ + "protocols": ["tcp", "tls"], + "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"}, {"port":9123}], + "id": "...", +} +``` + +TCP or TLS connections originating from IPs in CIDR range "10.1.0.0/16" or IP +address "10.2.2.2" or Port "9123" would match such Route. + +### Request Destination + +
+ **Note:** This section only applies to TCP and TLS routes. +
+ +The `destinations` attribute, similarly to `sources`, +allows matching a route by a list of incoming connection IP and/or port, but +uses the destination of the TCP/TLS connection as routing attribute. + +### Request SNI + +When using secure protocols (`https`, `grpcs`, or `tls`), a [Server +Name Indication][SNI] can be used as a routing attribute. The following Route +allows routing via SNIs: + +```json +{ + "snis": ["foo.test", "example.com"], + "id": "..." +} +``` + +Incoming requests with a matching hostname set in the TLS connection's SNI +extension would be routed to this Route. As mentioned, SNI routing applies not +only to TLS, but also to other protocols carried over TLS - such as HTTPS and +If multiple SNIs are specified in the Route, any of them can match with the incoming request's SNI. +with the incoming request (OR relationship between the names). + +The SNI is indicated at TLS handshake time and cannot be modified after the TLS connection has +been established. This means, for example, that multiple requests reusing the same keepalive connection +will have the same SNI hostname while performing router match, regardless of the `Host` header. +has been established. This means keepalive connections that send multiple requests +will have the same SNI hostnames while performing router match +(regardless of the `Host` header). + +Please note that creating a route with mismatched SNI and `Host` header matcher +is possible, but generally discouraged. + +## Matching priorities + +A Route may define matching rules based on its `headers`, `hosts`, `paths`, and +`methods` (plus `snis` for secure routes - `"https"`, `"grpcs"`, `"tls"`) +fields. For Kong to match an incoming request to a Route, all existing fields +must be satisfied. However, Kong allows for quite some flexibility by allowing +two or more Routes to be configured with fields containing the same values - +when this occurs, Kong applies a priority rule. + +The rule is: **when evaluating a request, Kong will first try to match the +Routes with the most rules**. + +For example, if two Routes are configured like so: + +```json +{ + "hosts": ["example.com"], + "service": { + "id": "..." + } +}, +{ + "hosts": ["example.com"], + "methods": ["POST"], + "service": { + "id": "..." + } +} +``` + +The second Route has a `hosts` field **and** a `methods` field, so it will be +evaluated first by Kong. By doing so, we avoid the first Route "shadowing" +calls intended for the second one. + +Thus, this request will match the first Route + +```http +GET / HTTP/1.1 +Host: example.com +``` + +And this request will match the second one: + +```http +POST / HTTP/1.1 +Host: example.com +``` + +Following this logic, if a third Route was to be configured with a `hosts` +field, a `methods` field, and a `uris` field, it would be evaluated first by +Kong. + +If the rule count for the given request is the same in two Routes `A` and +`B`, then the following tiebreaker rules will be applied in the order they +are listed. Route `A` will be selected over `B` if: + +* `A` has only "plain" Host headers and `B` has has one or more "wildcard" + host headers +* `A` has more non-Host headers than `B`. +* `A` has at least one "regex" paths and `B` has only "plain" paths. +* `A`'s longer path is longer than `B`'s longer path. +* `A.created_at < B.created_at` + + +[Back to top](#introduction) + +## Proxying behavior + +The proxying rules above detail how Kong forwards incoming requests to your +upstream services. Below, we detail what happens internally between the time +Kong *matches* an HTTP request with a registered Route, and the actual +*forwarding* of the request. + +[Back to top](#introduction) + +### 1. Load balancing + +Kong implements load balancing capabilities to distribute proxied +requests across a pool of instances of an upstream service. + +You can find more information about configuring load balancing by consulting +the [Load Balancing Reference][load-balancing-reference]. + +[Back to top](#introduction) + +### 2. Plugins execution + +Kong is extensible via "plugins" that hook themselves in the request/response +lifecycle of the proxied requests. Plugins can perform a variety of operations +in your environment and/or transformations on the proxied request. + +Plugins can be configured to run globally (for all proxied traffic) or on +specific Routes and Services. In both cases, you must create a [plugin +configuration][plugin-configuration-object] via the Admin API. + +Once a Route has been matched (and its associated Service entity), Kong will +run plugins associated to either of those entities. Plugins configured on a +Route run before plugins configured on a Service, but otherwise, the usual +rules of [plugins association][plugin-association-rules] apply. + +These configured plugins will run their `access` phase, which you can find more +information about in the [Plugin development guide][plugin-development-guide]. + +[Back to top](#introduction) + +### 3. Proxying & upstream timeouts + +Once Kong has executed all the necessary logic (including plugins), it is ready +to forward the request to your upstream service. This is done via Nginx's +[ngx_http_proxy_module][ngx-http-proxy-module]. You can configure the desired +timeouts for the connection between Kong and a given upstream, via the following +properties of a Service: + +- `connect_timeout`: defines in milliseconds the timeout for + establishing a connection to your upstream service. Defaults to `60000`. +- `write_timeout`: defines in milliseconds a timeout between two + successive write operations for transmitting a request to your upstream + service. Defaults to `60000`. +- `read_timeout`: defines in milliseconds a timeout between two + successive read operations for receiving a request from your upstream + service. Defaults to `60000`. + +Kong will send the request over HTTP/1.1, and set the following headers: + +- `Host: `, as previously described in this document. +- `Connection: keep-alive`, to allow for reusing the upstream connections. +- `X-Real-IP: `, where `$remote_addr` is the variable bearing + the same name provided by + [ngx_http_core_module][ngx-remote-addr-variable]. Please note that the + `$remote_addr` is likely overridden by + [ngx_http_realip_module][ngx-http-realip-module]. +- `X-Forwarded-For:
`, where `
` is the content of + `$realip_remote_addr` provided by + [ngx_http_realip_module][ngx-http-realip-module] appended to the request + header with the same name. +- `X-Forwarded-Proto: `, where `` is the protocol used by + the client. In the case where `$realip_remote_addr` is one of the **trusted** + addresses, the request header with the same name gets forwarded if provided. + Otherwise, the value of the `$scheme` variable provided by + [ngx_http_core_module][ngx-scheme-variable] will be used. +- `X-Forwarded-Host: `, where `` is the host name sent by + the client. In the case where `$realip_remote_addr` is one of the **trusted** + addresses, the request header with the same name gets forwarded if provided. + Otherwise, the value of the `$host` variable provided by + [ngx_http_core_module][ngx-host-variable] will be used. +- `X-Forwarded-Port: `, where `` is the port of the server which + accepted a request. In the case where `$realip_remote_addr` is one of the + **trusted** addresses, the request header with the same name gets forwarded + if provided. Otherwise, the value of the `$server_port` variable provided by + [ngx_http_core_module][ngx-server-port-variable] will be used. +- `X-Forwarded-Prefix: `, where `` is the path of the request which + was accepted by Kong. In the case where `$realip_remote_addr` is one of the + **trusted** addresses, the request header with the same name gets forwarded + if provided. Otherwise, the value of the `$request_uri` variable (with + the query string stripped) provided by [ngx_http_core_module][ngx-server-port-variable] + will be used. **Note**: Kong will return `"/"` for an empty path, but it does not do any other normalization on the request path. + +All the other request headers are forwarded as-is by Kong. + +One exception to this is made when using the WebSocket protocol. If so, Kong +will set the following headers to allow for upgrading the protocol between the +client and your upstream services: + +- `Connection: Upgrade` +- `Upgrade: websocket` + +More information on this topic is covered in the +[Proxy WebSocket traffic][proxy-websocket] section. + +[Back to top](#introduction) + +### 4. Errors & retries + +Whenever an error occurs during proxying, Kong will use the underlying +Nginx [retries][ngx-http-proxy-retries] mechanism to pass the request on to +the next upstream. + +There are two configurable elements here: + +1. The number of retries: this can be configured per Service using the + `retries` property. See the [Admin API][API] for more details on this. + +2. What exactly constitutes an error: here Kong uses the Nginx defaults, which + means an error or timeout occurring while establishing a connection with the + server, passing a request to it, or reading the response headers. + +The second option is based on Nginx's +[proxy_next_upstream][proxy_next_upstream] directive. This option is not +directly configurable through Kong, but can be added using a custom Nginx +configuration. See the [configuration reference][configuration-reference] for +more details. + +[Back to top](#introduction) + +### 5. Response + +Kong receives the response from the upstream service and sends it back to the +downstream client in a streaming fashion. At this point Kong will execute +subsequent plugins added to the Route and/or Service that implement a hook in +the `header_filter` phase. + +Once the `header_filter` phase of all registered plugins has been executed, the +following headers will be added by Kong and the full set of headers be sent to +the client: + +- `Via: kong/x.x.x`, where `x.x.x` is the Kong version in use +- `X-Kong-Proxy-Latency: `, where `latency` is the time in milliseconds + between Kong receiving the request from the client and sending the request to + your upstream service. +- `X-Kong-Upstream-Latency: `, where `latency` is the time in + milliseconds that Kong was waiting for the first byte of the upstream service + response. + +Once the headers are sent to the client, Kong will start executing +registered plugins for the Route and/or Service that implement the +`body_filter` hook. This hook may be called multiple times, due to the +streaming nature of Nginx. Each chunk of the upstream response that is +successfully processed by such `body_filter` hooks is sent back to the client. +You can find more information about the `body_filter` hook in the [Plugin +development guide][plugin-development-guide]. + +[Back to top](#introduction) + +## Configuring a fallback Route + +As a practical use-case and example of the flexibility offered by Kong's +proxying capabilities, let's try to implement a "fallback Route", so that in +order to avoid Kong responding with an HTTP `404`, "no route found", we can +catch such requests and proxy them to a special upstream service, or apply a +plugin to it (such a plugin could, for example, terminate the request with a +different status code or response without proxying the request). + +Here is an example of such a fallback Route: + +```json +{ + "paths": ["/"], + "service": { + "id": "..." + } +} +``` + +As you can guess, any HTTP request made to Kong would actually match this +Route, since all URIs are prefixed by the root character `/`. As we know from +the [Request path][proxy-request-path] section, the longest URL paths are +evaluated first by Kong, so the `/` path will eventually be evaluated last by +Kong, and effectively provide a "fallback" Route, only matched as a last +resort. You can then send traffic to a special Service or apply any plugin you +wish on this Route. + +[Back to top](#introduction) + +## Configuring TLS for a Route + +Kong provides a way to dynamically serve TLS certificates on a per-connection +basis. TLS certificates are directly handled by the core, and configurable via +the Admin API. Clients connecting to Kong over TLS must support the [Server +Name Indication][SNI] extension to make use of this feature. + +TLS certificates are handled by two resources in the Kong Admin API: + +- `/certificates`, which stores your keys and certificates. +- `/snis`, which associates a registered certificate with a Server Name + Indication. + +You can find the documentation for those two resources in the +[Admin API Reference][API]. + +Here is how to configure a TLS certificate on a given Route: first, upload +your TLS certificate and key via the Admin API: + +```bash +$ curl -i -X POST http://localhost:8001/certificates \ + -F "cert=@/path/to/cert.pem" \ + -F "key=@/path/to/cert.key" \ + -F "snis=*.tls-example.com,other-tls-example.com" +HTTP/1.1 201 Created +... +``` + +The `snis` form parameter is a sugar parameter, directly inserting an SNI and +associating the uploaded certificate to it. + +Note that one of the SNI names defined in `snis` above contains a wildcard +(`*.tls-example.com`). An SNI may contain a single wildcard in the leftmost (prefix) or +rightmost (suffix) postion. This can be useful when maintaining multiple subdomains. A +single `sni` configured with a wildcard name can be used to match multiple +subdomains, instead of creating an SNI for each. + +Valid wildcard positions are `mydomain.*`, `*.mydomain.com`, and `*.www.mydomain.com`. + +A default certificate can be added using the following parameters in Kong configuration: +1. [`ssl_cert`](/latest/configuration/#ssl_cert) +2. [`ssl_cert_key`](/latest/configuration/#ssl_cert_key) + +Or, by dynamically configuring the default certificate with an SNI of `*`: + +```bash +$ curl -i -X POST http://localhost:8001/certificates \ + -F "cert=@/path/to/default-cert.pem" \ + -F "key=@/path/to/default-cert.key" \ + -F "snis=*" +HTTP/1.1 201 Created +... +``` + +Matching of `snis` respects the following priority: + + 1. Exact SNI matching certificate + 2. Search for a certificate by prefix wildcard + 3. Search for a certificate by suffix wildcard + 4. Search for a certificate associated with the SNI `*` + 5. The default certificate on the file system + +You must now register the following Route within Kong. We will match requests +to this Route using only the Host header for convenience: + +```bash +$ curl -i -X POST http://localhost:8001/routes \ + -d 'hosts=prefix.tls-example.com,other-tls-example.com' \ + -d 'service.id=d54da06c-d69f-4910-8896-915c63c270cd' +HTTP/1.1 201 Created +... +``` + +You can now expect the Route to be served over HTTPS by Kong: + +```bash +$ curl -i https://localhost:8443/ \ + -H "Host: prefix.tls-example.com" +HTTP/1.1 200 OK +... +``` + +When establishing the connection and negotiating the TLS handshake, if your +client sends `prefix.tls-example.com` as part of the SNI extension, Kong will serve +the `cert.pem` certificate previously configured. This is the same for both HTTPS and +TLS connections. + +[Back to top](#introduction) + +### Restricting the client protocol (HTTP/HTTPS, GRPC/GRPCS, TCP/TLS) + +Routes have a `protocols` property to restrict the client protocol they should +listen for. This attribute accepts a set of values, which can be `"http"`, +`"https"`, `"grpc"`, `"grpcs"`, `"tcp"`, or `"tls"`. + +A Route with `http` and `https` will accept traffic in both protocols. + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["http", "https"], + "service": { + "id": "..." + } +} +``` + +Not specifying any protocol has the same effect, since routes default to +`["http", "https"]`. + +However, a Route with *only* `https` would _only_ accept traffic over HTTPS. It +would _also_ accept unencrypted traffic _if_ TLS termination previously +occurred from a trusted IP. TLS termination is considered valid when the +request comes from one of the configured IPs in +[trusted_ips][configuration-trusted-ips] and if the `X-Forwarded-Proto: https` +header is set: + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["https"], + "service": { + "id": "..." + } +} +``` + +If a Route such as the above matches a request, but that request is in +plain-text without valid prior TLS termination, Kong responds with: + +```http +HTTP/1.1 426 Upgrade Required +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: Upgrade +Upgrade: TLS/1.2, HTTP/1.1 +Server: kong/x.y.z + +{"message":"Please use HTTPS protocol"} +``` + +Since Kong 1.0 it's possible to create routes for raw TCP (not necessarily HTTP) +connections by using `"tcp"` in the `protocols` attribute: + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["tcp"], + "service": { + "id": "..." + } +} +``` + +Similarly, we can create routes which accept raw TLS traffic (not necessarily HTTPS) with +the `"tls"` value: + +```json +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["tls"], + "service": { + "id": "..." + } +} +``` + +A Route with *only* `TLS` would _only_ accept traffic over TLS. + +It is also possible to accept both TCP and TLS simultaneously: + +``` +{ + "hosts": ["..."], + "paths": ["..."], + "methods": ["..."], + "protocols": ["tcp", "tls"], + "service": { + "id": "..." + } +} + +``` + +For L4 TLS proxy to work, it is necessary to create route that accepts +the `tls` `protocol`, as well as having the appropriate TLS certificate +uploaded and their `sni` attribute properly set to match incoming connection's +SNI. Please refer to the [Configuring TLS for a Route](#configuring-tls-for-a-route) +section above for instructions on setting this up. + +[Back to top](#introduction) + +## Proxy WebSocket traffic + +Kong supports WebSocket traffic thanks to the underlying Nginx implementation. +When you wish to establish a WebSocket connection between a client and your +upstream services *through* Kong, you must establish a WebSocket handshake. +This is done via the HTTP Upgrade mechanism. This is what your client request +made to Kong would look like: + +```http +GET / HTTP/1.1 +Connection: Upgrade +Host: my-websocket-api.com +Upgrade: WebSocket +``` + +This will make Kong forward the `Connection` and `Upgrade` headers to your +upstream service, instead of dismissing them due to the hop-by-hop nature of a +standard HTTP proxy. + +[Back to top](#introduction) + +### WebSocket and TLS + +Kong will accept `ws` and `wss` connections on its respective `http` and +`https` ports. To enforce TLS connections from clients, set the `protocols` +property of the [Route][route-entity] to `https` only. + +When setting up the [Service][service-entity] to point to your upstream +WebSocket service, you should carefully pick the protocol you want to use +between Kong and the upstream. If you want to use TLS (`wss`), then the +upstream WebSocket service must be defined using the `https` protocol in the +Service `protocol` property, and the proper port (usually 443). To connect +without TLS (`ws`), then the `http` protocol and port (usually 80) should be +used in `protocol` instead. + +If you want Kong to terminate TLS, you can accept `wss` only from the +client, but proxy to the upstream service over plain text, or `ws`. + +[Back to top](#introduction) + +## Proxy gRPC traffic + +Starting with version 1.3, gRPC proxying is natively supported in Kong. In order +to manage gRPC services and proxy gRPC requests with Kong, create Services and +Routes for your gRPC Services (check out the [Configuring a gRPC Service guide][conf-grpc-service]). + +Note that in Kong 1.3 only observability and logging plugins are supported with +gRPC - plugins known to be supported with gRPC have "grpc" and "grpcs" listed +under the supported protocols field in their Kong Hub page - for example, +check out the [File Log][file-log] plugin's page. + +[Back to top](#introduction) + +## Proxy TCP/TLS traffic + +Starting with version 1.0, TCP and TLS proxying is natively supported in Kong. + +In this mode, data of incoming connections reaching the `stream_listen` endpoints will +be passed through to the upstream. It is possible to terminate TLS connections +from clients using this mode as well. + +To use this mode, aside from defining `stream_listen`, appropriate Route/Service +object with protocol types of `tcp` or `tls` should be created. + +If TLS termination by Kong is desired, the following conditions must be met: + +1. The Kong port where TLS connection connects to must have the `ssl` flag enabled +2. A certificate/key that can be used for TLS termination must be present inside Kong, + as shown in [Configuring TLS for a Route](#configuring-tls-for-a-route) + +Kong will use the connecting client's TLS SNI server name extension to find +the appropriate TLS certificate to use. + +On the Service side, depends on whether connection between Kong and the upstream +service need to be encrypted, `tcp` or `tls` protocol types can be set accordingly. +This means all of the below setup are supported in this mode: + +1. Client <- TLS -> Kong <- TLS -> Upstream +2. Client <- TLS -> Kong <- Cleartext -> Upstream +3. Client <- Cleartext -> Kong <- TLS -> Upstream + +**Note:** In L4 proxy mode, only plugins that has `tcp` or `tls` in the supported +protocol list are supported. This list can be found in their respective documentation +on [Kong Hub](https://docs.konghq.com/hub/). + +[Back to top](#introduction) + +## Conclusion + +Through this guide, we hope you gained knowledge of the underlying proxying +mechanism of Kong, from how does a request match a Route to be routed to its +associated Service, on to how to allow for using the WebSocket protocol or +setup dynamic TLS certificates. + +This website is Open-Source and can be found at +[github.com/Kong/docs.konghq.com](https://github.com/Kong/docs.konghq.com/). +Feel free to provide feedback to this document there, or propose improvements! + +If you haven't already, we suggest that you also read the [Load balancing +Reference][load-balancing-reference], as it closely relates to the topic we +just covered. + +[Back to top](#introduction) + +[plugin-configuration-object]: /{{page.kong_version}}/admin-api#plugin-object +[plugin-development-guide]: /{{page.kong_version}}/plugin-development +[plugin-association-rules]: /{{page.kong_version}}/admin-api/#precedence +[proxy-websocket]: /{{page.kong_version}}/proxy/#proxy-websocket-traffic +[load-balancing-reference]: /{{page.kong_version}}/loadbalancing +[configuration-reference]: /{{page.kong_version}}/configuration/ +[configuration-trusted-ips]: /{{page.kong_version}}/configuration/#trusted_ips +[configuring-a-service]: /{{page.kong_version}}/getting-started/configuring-a-service +[API]: /{{page.kong_version}}/admin-api +[service-entity]: /{{page.kong_version}}/admin-api/#add-service +[route-entity]: /{{page.kong_version}}/admin-api/#add-route + +[ngx-http-proxy-module]: http://nginx.org/en/docs/http/ngx_http_proxy_module.html +[ngx-http-realip-module]: http://nginx.org/en/docs/http/ngx_http_realip_module.html +[ngx-remote-addr-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_remote_addr +[ngx-scheme-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_scheme +[ngx-host-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_host +[ngx-server-port-variable]: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_server_port +[ngx-http-proxy-retries]: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_tries +[SNI]: https://en.wikipedia.org/wiki/Server_Name_Indication +[conf-grpc-service]: /{{page.kong_version}}/getting-started/configuring-a-grpc-service +[file-log]: //file-log diff --git a/app/2.2.x/secure-admin-api.md b/app/2.2.x/secure-admin-api.md new file mode 100644 index 000000000000..2a4d4f6125c6 --- /dev/null +++ b/app/2.2.x/secure-admin-api.md @@ -0,0 +1,155 @@ +--- +title: Securing the Admin API +--- + +## Introduction + +Kong's Admin API provides a RESTful interface for administration and +configuration of Services, Routes, Plugins, Consumers, and Credentials. Because this +API allows full control of Kong, it is important to secure this API against +unwanted access. This document describes a few possible approaches to securing +the Admin API. + +## Network Layer Access Restrictions + +### Minimal Listening Footprint + +By default since its 0.12.0 release, Kong will only accept requests from the +local interface, as specified in its default `admin_listen` value: + +``` +admin_listen = 127.0.0.1:8001 +``` + +If you change this value, always ensure to keep the listening footprint to a +minimum, in order to avoid exposing your Admin API to third-parties, which +could seriously compromise the security of your Kong cluster as a whole. +For example, **avoid binding Kong to all of your interfaces**, by using +values such as `0.0.0.0:8001`. + +[Back to top](#introduction) + +### Layer 3/4 Network Controls + +In cases where the Admin API must be exposed beyond a localhost interface, +network security best practices dictate that network-layer access be restricted +as much as possible. Consider an environment in which Kong listens on a private +network interface, but should only be accessed by a small subset of an IP range. +In such a case, host-based firewalls (e.g. iptables) are useful in limiting +input traffic ranges. For example: + + +```bash +# assume that Kong is listening on the address defined below, as defined as a +# /24 CIDR block, and only a select few hosts in this range should have access + +$ grep admin_listen /etc/kong/kong.conf +admin_listen 10.10.10.3:8001 + +# explicitly allow TCP packets on port 8001 from the Kong node itself +# this is not necessary if Admin API requests are not sent from the node +$ iptables -A INPUT -s 10.10.10.3 -m tcp -p tcp --dport 8001 -j ACCEPT + +# explicitly allow TCP packets on port 8001 from the following addresses +$ iptables -A INPUT -s 10.10.10.4 -m tcp -p tcp --dport 8001 -j ACCEPT +$ iptables -A INPUT -s 10.10.10.5 -m tcp -p tcp --dport 8001 -j ACCEPT + +# drop all TCP packets on port 8001 not in the above IP list +$ iptables -A INPUT -m tcp -p tcp --dport 8001 -j DROP + +``` + +Additional controls, such as similar ACLs applied at a network device level, are +encouraged, but fall outside the scope of this document. + +[Back to top](#introduction) + +## Kong API Loopback + +Kong's routing design allows it to serve as a proxy for the Admin API itself. In +this manner, Kong itself can be used to provide fine-grained access control to +the Admin API. Such an environment requires bootstrapping a new Service that defines +the `admin_listen` address as the Service's `url`. For example: + +```bash +# assume that Kong has defined admin_listen as 127.0.0.1:8001, and we want to +# reach the Admin API via the url `/admin-api` + +$ curl -X POST http://localhost:8001/services \ + --data name=my-service \ + --data url=http://example.com/some_api + +# we can now transparently reach the Admin API through the proxy server +$ curl localhost:8000/admin-api/services +{ + "data": [{ + "id": "a5fb8d9b-a99d-40e9-9d35-72d42a62d83a", + "created_at": 1422386534, + "updated_at": 1422386534, + "name": "my-service", + "retries": 5, + "protocol": "http", + "host": "example.com", + "port": 80, + "path": "/some_api", + "connect_timeout": 60000, + "write_timeout": 60000, + "read_timeout": 60000, + "tags": ["user-level", "low-priority"], + "client_certificate": {"id":"51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"}, + "tls_verify": true, + "tls_verify_depth": null, + "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"] + }], + "next": "http://localhost:8001/services?offset=6378122c-a0a1-438d-a5c6-efabae9fb969" +} +``` + +From here, simply apply desired Kong-specific security controls (such as +[basic][basic-auth] or [key authentication][key-auth], +[IP restrictions][ip-restriction], or [access control lists][acl]) as you would +normally to any other Kong API. + +[Back to top](#introduction) + +## Custom Nginx Configuration + +Kong is tightly coupled with Nginx as an HTTP daemon, and can thus be integrated +into environments with custom Nginx configurations. In this manner, use cases +with complex security/access control requirements can use the full power of +Nginx/OpenResty to build server/location blocks to house the Admin API as +necessary. This allows such environments to leverage native Nginx authorization +and authentication mechanisms, ACL modules, etc., in addition to providing the +OpenResty environment on which custom/complex security controls can be built. + +For more information on integrating Kong into custom Nginx configurations, see +[Custom Nginx configuration & embedding Kong][custom-configuration]. + +[Back to top](#introduction) + +## Role Based Access Control ## + +
+ Enterprise-Only This feature is only available with an + Enterprise Subscription. +
+ +Enterprise users can configure role-based access control to secure access to the +Admin API. RBAC allows for fine-grained control over resource access based on +a model of user roles and permissions. Users are assigned to one or more roles, +which each in turn possess one or more permissions granting or denying access +to a particular resource. In this way, fine-grained control over specific Admin +API resources can be enforced, while scaling to allow complex, case-specific +uses. + +If you are not a Kong Enterprise customer, you can inquire about our +Enterprise offering by [contacting us](/enterprise). + +[Back to top](#introduction) + + +[acl]: /plugins/acl +[basic-auth]: /plugins/basic-authentication/ +[custom-configuration]: /{{page.kong_version}}/configuration/#custom-nginx-configuration +[ip-restriction]: /plugins/ip-restriction +[key-auth]: /plugins/key-authentication diff --git a/app/2.2.x/sizing-guidelines.md b/app/2.2.x/sizing-guidelines.md new file mode 100644 index 000000000000..3ddfca573442 --- /dev/null +++ b/app/2.2.x/sizing-guidelines.md @@ -0,0 +1,156 @@ +--- +title: Resource Sizing Guidelines +--- + +## Introduction + +This document discusses the performance characteristics of Kong, and offers +recommendations on sizing with respect to resource allocation based on expected +Kong configuration and traffic patterns. We present these recommendations as +a baseline guide; specific tuning or benchmarking efforts should be undertaken +for performance-critical environments. + +## General Resource Guidelines + +### Kong Resources + +Kong is designed to operate in a variety of deployment environments. In general +it has no minimum system requirements to operate. Resource requirements will +vary substantially based on configuration; the following high-level matricies +offer a guideline for determining system requirements based overall +configuration and performance requirements. Consider the following simplified +examples, where latency and throughput requirements are considered on a per-node +basis: + +| Size | Number of Configured Entities | Latency Requirements | Throughput Requirements | Usage Pattern | +|---|---|---|---|---| +| Small | < 100 | < 100 ms | < 500 RPS | Dev/test environments; latency-insensitive gateways | +| Medium | < 1000 | < 20 ms | < 2500 RPS | Production clusters; greenfield traffic deployments | +| Large | < 10000 | < 10 ms | < 10000 RPS | Mission-critical clusters; legacy & greenfield traffic; central enterprise-grade gateways | + +The above provides a path to determine a rough outlook on the usage +requirements. Based on the expected size and demand of the cluster, we recommend +the following resource allocations as a starting point: + +| Size | CPU | RAM | Typical Cloud Instance Sizes | +|---|---|---|---|---| +| Small | 1-2 cores | 2-4 GB | **AWS**: t3.medium
**GCP**: n1-standard-1
**Azure**: Standard A1 v2 | +| Medium | 2-4 cores | 4-8 GB | **AWS**: m5.large
**GCP**: n1-standard-4
**Azure**: Standard A1 v4 | +| Large | 8-16 cores | 16-32 GB | **AWS**: c5.xlarge
**GCP**: n1-highcpu-16
**Azure**: F8s v2 | + +We strongly discourage the use of throttled cloud instance types (such as the +AWS `t2` or `t3` series of machines) in large clusters, as CPU throttling would +be detrimental to Kong's performance. We also recommend testing and verifying +the bandwidth availability for a given instance class. Bandwidth requirements +for Kong will depend on the shape and volume of traffic flowing through the +cluster. + +We recommend defining the `mem_cache_size` configuration as large as possible, +while still providing adequate resources to the operating system and any other +processes running adjacent to Kong. This configuration allows Kong to take +maximum advantage of in-memory cache, and reduce the number of trips to the +database. Additionally, each Kong worker process maintains its own memory +allocations, and must be accounted for when provisioning memory. By default one +worker process runs per number of available CPU cores. In general, we recommend +allowing for ~ 500MB of memory allocated per worker process. Thus, on a machine +with 4 CPU cores and 8 GB of RAM available, we recommend allocating between 4-6 +GB to cache via the `mem_cache_size` directive, depending on what other +processes are running alongside Kong. + +### Database Resources + +Kong is intentionally relies on the database as little as possible during +high-traffic operations. Configuration data for a Kong cluster is meant to be +read as infrequently, and held in memory as long as possible. As such, database +resource requirements are generally lower than those of compute environments +running Kong. + +Kong generally executes a spikey access pattern to its backing database. When a +node first starts, or configuration for a given entity changes, Kong reads the +relevant configuration from the database. Query patterns are typically simple +and follow schema indexes. It's important to provision sufficient database +resources in order to handle spikey query patterns. Specific resource +requirements vary widely based on the number and rate of change of configured +entities, the rate at which Kong processes are (re)started within the cluster, +and the size of Kong's in-memory cache. + +## Scaling Dimensions + +Kong's is designed to be highly-performant, handling a large volume of request +traffic and proxying requests with minimal latency. Understanding how various +configuration scenarios impacts request traffic, and the Kong cluster itself, is +a crucial step in successfully deploying Kong. + +Kong measures performance in two dimensions: _latency_ and _throughput_. +_Latency_, in this context, refers to the delay between the downstream client +sending a request and receiving a response. Kong measures latency introduced +into the request in terms of microseconds or milliseconds. Increasing the number +of Routes and/or Plugins in a Kong cluster will increase the amount of latency +that is added into each request. _Throughput_ refers to number of simultaneous +requests that Kong can process in a given time span, typically measured in +seconds or minutes. + +In general, these two dimensions have an inversely proportional relationship +when all other factors remain the same: decreasing the latency introduced into +each request allows the maximum throughput in Kong to increase, as there is less +CPU time spent handling each request, and thus more CPU available for processing +traffic as a whole. Kong is designed to scale horizontally to be able to add +more overall compute power for configurations that add substantial latency into +requests, while needing to meet specific throughput requirements. + +In general, Kong's maximum throughput is a CPU-bound dimension, and minumim +latency is memory-bound. That is, adding more available compute power to the +cluster to a latency-sensitive workload would be less beneficial than making +available more memory for database caching. Likewise, throughput-sensitive +workloads are dependant on both adequate memory and CPU resources, but adding +more cache memory will do little to increase maximum throughput; adding more +compute power by scaling Kong vertically and/or horizontally provides +near-unlimited throughput capacity. + +Performance benchmarking and optimization as a whole is a complex exercise that +must account for a variety of factors, including those external to Kong, such as +the behavior of upstream services, or the health of the underlying hardware on +which Kong is running. + +## Performance Characteristics + +There are a number of factors that impact Kong's behavior with respect to +performance, including: + +* **Number of configured Routes and Services**. Increasing the count of Routes +and Services on the cluster will require more CPU to evaluate the request. +Kong's request router is designed to be highly performant; we have seen clusters +of Kong nodes in the wild serving tens of thousands of Routes with minimal +impact to latency as a result of request route evaluation. + +* **Number of configured Consumers and Credentials**. Consumer and credential +data is stored in Kong's datastore (either PostgreSQL or Cassandra, or the +`kong.yml` file in DB-less environments). Kong caches this data in memory to +reduce database load and latency during request processing. Increasing the count +of Consumers and Credentials will require more memory available for Kong to hold +data in cache; if there is not enough memory available to cache all requested +database entities, request latency will increase as Kong will need to query the +database more frequently to satisfy requests. + +* **Number of configured Plugins**. Increasing the count of Plugins on the +cluster will require more CPU to iterate through plugins during request +processing. Executing plugins comes with a varying cost depending on the nature +of the plugin; for example, a lightweight authentication plugin like `key-auth` +requires less resource availability than a plugin that performs complex +transformations of an HTTP request or response. + +* **Cardinality of configured Plugins**. _Cardinality_ here refers to the number +of distinct plugin types that are configured on the cluster. For example, a +cluster with one each of `ip-restriction`, `key-auth`, `bot-detection`, +`rate-limiting`, and `http-log` plugins has a higher plugin cardinality than a +cluster with one thousand `rate-limiting` plugins applied at the route level. +With each additional plugin type added to the cluster, Kong spends more time +evaluating whether to execute a given plugin for a given request. Increasing the +cardinality of configured plugins requires more CPU power, as the process to +evaluate plugins is a CPU-constrained task. + +* **Request and response size**. Requests with large HTTP bodies, either in the +request or response, will take longer to process, as Kong must buffer the +request to disk before proxying it. This allows Kong to handle a large volume of +simultaneous traffic without running out of memory, but the nature of buffered +requests can result in increased latency. diff --git a/app/2.2.x/systemd.md b/app/2.2.x/systemd.md new file mode 100644 index 000000000000..fc84ef23bb98 --- /dev/null +++ b/app/2.2.x/systemd.md @@ -0,0 +1,145 @@ +--- +title: Control Kong through systemd +toc: false +--- + +### Introduction + +This document includes instructions on how to integrate Kong with +[systemd](https://freedesktop.org/wiki/Software/systemd/) for +Debian and RPM based packages. Note that some of the supported GNU/Linux +distributions for Kong may not have adopted systemd as their default init +system (for example, CentOS 6 and RHEL 6). For the following instructions, it +is assumed that Kong has already been [installed and +configured](https://konghq.com/install/) on a systemd-supported GNU/Linux +distribution. + +## Start Kong + +``` +$ sudo systemctl start kong +``` + +## Stop Kong + +``` +$ sudo systemctl stop kong +``` + +## Start Kong automatically at system boot + +To enable Kong to automatically start at system boot: + +``` +$ sudo systemctl enable kong +``` + +To disable Kong from automatically starting at system boot: + +``` +$ sudo systemctl disable kong +``` + +## Restart Kong + +``` +$ sudo systemctl restart kong +``` + +## Query Kong status + +``` +$ sudo systemctl status kong +``` + +## Customize the Kong unit file + +The official systemd service is located at `/lib/systemd/system/kong.service`. +For scenarios where customizations are needed (for example, configuring Kong +or modifying the service file behavior), we recommend to create another +service at `/etc/systemd/system/kong.service` to avoid conflicts upon +reinstalling or upgrading Kong. + +All environment variables prefixed with `KONG_` and capitalized will override +the settings specified in the `/etc/kong/kong.conf.default` file. For example: +`log_level = debug` in the .conf file translates to the `KONG_LOG_LEVEL=debug` +environment variable. + +There is also the possibility of opting to _not_ use environment variables in +the service file but instead use a configuration file. In this case, modify +the `ExecStartPre` systemd directive to execute `kong prepare` with the `-c` +argument to point to your configuration file. For example, if you have a +custom configuration file at `/etc/kong/kong.conf`, modify the `ExecStartPre` +directive as follows: + +``` +ExecStartPre=/usr/local/bin/kong prepare -p /usr/local/kong -c /etc/kong/kong.conf +``` + +When linking non environment files using the `EnvironmentFile` systemd +directive, note that the systemd parser will only recognize environment +variables assignments. For example, if one of the Kong's default configuration +files are linked (`/etc/kong/kong.conf.default` and `/etc/kong.conf`), non +environment variables assignments in the file could lead to systemd errors. In +this case, systemd will not allow the Kong service to be started. For this +reason, we recommend specifying an `EnvironmentFile` other than the default +ones: + +``` +EnvironmentFile=/etc/kong/kong_env.conf +``` + +### Logging to syslog and journald + +In this case, adding the below `Environment` systemd directives to your +customized systemd service file at `/etc/systemd/system/kong.service` will do +it: + +``` +Environment=KONG_PROXY_ACCESS_LOG=syslog:server=unix:/dev/log +Environment=KONG_PROXY_ERROR_LOG=syslog:server=unix:/dev/log +Environment=KONG_ADMIN_ACCESS_LOG=syslog:server=unix:/dev/log +Environment=KONG_ADMIN_ERROR_LOG=syslog:server=unix:/dev/log +``` + +To view the journald logs: + `journalctl -u kong` + +To view the syslog logs: + `tail -F /var/log/syslog` + +### Customize Kong's Nginx instance [using the Nginx directive injection system + +To use the [Nginx directive injection system](/{{page.kong_version}}/configuration/#injecting-individual-nginx-directives), +add the below `Environment` systemd directive to your custom service at +`/etc/systemd/system/kong.service` if environment variables are preferred. +Note the quoting rules defined by systemd to specify an environment variable +containing spaces: + +``` +Environment="KONG_NGINX_HTTP_OUTPUT_BUFFERS=4 64k" +``` + +### Customize Kong's Nginx instance using `--nginx-conf` + +To use the [`--nginx-conf` argument](/{{page.kong_version}}/configuration/#custom-nginx-templates), +modify the `ExecStartPre` systemd directive to execute `kong prepare` with the +`--nginx-conf` argument. For example, if you have a custom template at +`/usr/local/kong/custom-nginx.template`, modify the `ExecStartPre` directive +as follows: + +``` +ExecStartPre=/usr/local/bin/kong prepare -p /usr/local/kong --nginx-conf /usr/local/kong/custom-nginx.template +``` + +### Customize Kong's Nginx instance including files via the injected Nginx directives + +To [include files via the injected Nginx +directives](/{{page.kong_version}}/configuration/#including-files-via-injected-nginx-directives), +add the below `Environment` systemd directive to your custom service at +`/etc/systemd/system/kong.service` if environment variables are preferred: + +``` +Environment=KONG_NGINX_HTTP_INCLUDE=/path/to/your/my-server.kong.conf +``` + diff --git a/app/2.2.x/upgrading.md b/app/2.2.x/upgrading.md new file mode 100644 index 000000000000..dc8d586a0099 --- /dev/null +++ b/app/2.2.x/upgrading.md @@ -0,0 +1,3428 @@ +--- +title: Upgrade guide +skip_read_time: true +--- + +This document guides you through the process of upgrading Kong. First, check if +a section named "Upgrade to `x.x.x`" exists, with `x.x.x` being the version +you are planning to upgrade to. If such a section does not exist, the upgrade +you want to perform does not have any particular instructions, and you can +simply consult the [Suggested upgrade path](#suggested-upgrade-path). + +## Suggested upgrade path + +Unless indicated otherwise in one of the upgrade paths of this document, it is +possible to upgrade Kong **without downtime**: + +Assuming that Kong is already running on your system, acquire the latest +version from any of the available [installation +methods](https://getkong.org/install/) and proceed to install it, overriding +your previous installation. + +If you are planning to make modifications to your configuration, this is a +good time to do so. + +Then, run migration to upgrade your database schema: + +```shell +$ kong migrations up [-c configuration_file] +``` + +If the command is successful, and no migration ran +(no output), then you only have to +[reload](https://docs.konghq.com/1.0.x/cli/#kong-reload) Kong: + +```shell +$ kong reload [-c configuration_file] +``` + +**Reminder**: `kong reload` leverages the Nginx `reload` signal that seamlessly +starts new workers, which take over from old workers before those old workers +are terminated. In this way, Kong will serve new requests via the new +configuration, without dropping existing in-flight connections. + +## Upgrade to `2.2.0` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different depending on which previous version from which you are migrating. + +If you are migrating from 2.0.0 or 2.1.x, upgrading into 2.2.x is a minor upgrade, +but read below for important instructions on database migration, especially +for Cassandra users. + +If you are migrating from 1.x, upgrading into 2.2.x is a major upgrade, +so, in addition, be aware of any [breaking changes](#breaking-changes-2.0.0) +between the 1.x and 2.x series below, further detailed in the +[CHANGELOG.md](https://github.com/Kong/kong/blob/2.0.0/CHANGELOG.md) document. + + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +for the gateway are bundled and you can skip this section. + +If you are building your dependencies by hand, there are changes since the +previous release, so you will need to rebuild them with the latest patches. + +The required OpenResty version for kong 2.2.x is +[1.17.8.2](http://openresty.org/en/changelog-1015008.html). This is more recent +than the version in Kong 2.1.0 (which used `1.15.8.3`). In addition to an upgraded +OpenResty, you will need the correct [OpenResty +patches](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools/openresty-patches) +for this new version, including the latest release of +[lua-kong-nginx-module](https://github.com/Kong/lua-kong-nginx-module). +The [kong-build-tools](https://github.com/Kong/kong-build-tools) +repository contains [openresty-build-tools](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools), +which allows you to build OpenResty with the necessary patches +and modules easily. + +For Go support, you also need to build both your plugins and +the [Kong go-pluginserver](https://github.com/kong/go-pluginserver). +The documentation includes detailed [instructions on how to build +the plugin server and your plugins](https://docs.konghq.com/2.2.x/go/). + +#### 2. Template Changes + +There are **Changes in the Nginx configuration file**, between kong 2.0.0, +2.1.0 and 2.2.0. + +To view the configuration changes between versions, clone the +[Kong repository](https://github.com/kong/kong) and run `git diff` +on the configuration templates, using `-w` for greater readability. + +Here's how to see the differences between 2.0.0 and 2.2.0: + +``` +git clone https://github.com/kong/kong +cd kong +git diff -w 2.0.0 2.2.0 kong/templates/nginx_kong*.lua +``` + +To produce a patch file, use the following command: + +``` +git diff 2.0.0 2.2.0 kong/templates/nginx_kong*.lua > kong_config_changes.diff +``` + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `2.2.0` + +The lowest version that Kong 2.2.0 supports migrating from is 1.0.0. +If you are migrating from a version lower than 0.14.1, you need to +migrate to 0.14.1 first. Then, once you are migrating from 0.14.1, +please migrate to 1.5.0 first. + +The steps for upgrading from 0.14.1 to 1.5.0 are the same as upgrading +from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path), with the addition of the `kong +migrations migrate-apis` command, which you can use to migrate legacy +`apis` configurations. + +Once you migrated to 1.5.0, you can follow the instructions in the section +below to migrate to 2.2.0. + +##### Upgrade from `1.0.0` - `2.1.0` to `2.2.0` + +**Postgres** + +Kong 2.2.0 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that the new version of Kong is able to use +the database as it is migrated while the old Kong cluster keeps working until +it is time to decommission it. For this reason, the migration is split into +two steps, performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 2.2.0). + +1. Download 2.2.0, and configure it to point to the same datastore + as your old (1.0 to 2.0) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old (pre-2.1) and new (2.2.0) + clusters can now run simultaneously. Start provisioning 2.2.0 nodes, + but do not use their Admin API yet. If you need to perform Admin API + requests, these should be made to the old cluster's nodes. The reason + is to prevent the new cluster from generating data that is not understood + by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 2.2.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 2.2.0 cluster, + decommission your old nodes. +5. From your 2.2.0 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 2.2.0 nodes. + +**Cassandra** + +Due to internal changes, the table schemas used by Kong 2.2.0 on Cassandra +are incompatible with those used by Kong 2.0.0. Migrating using the usual commands +`kong migrations up` and `kong migrations finish` will require a small +window of downtime, since the old and new versions cannot use the +database at the same time. Alternatively, to keep your previous version fully +operational while the new one initializes, you will need to transfer the +data to a new keyspace via a database dump, as described below: + +1. Download 2.2.0, and configure it to point to a new keyspace. + Run `kong migrations bootstrap`. +2. Once that finishes running, both the old (pre-2.1) and new (2.2.0) + clusters can now run simultaneously, but the new cluster does not + have any data yet. +3. On the old cluster, run `kong config db_export`. This will create + a file `kong.yml` with a database dump. +4. Transfer the file to the new cluster and run + `kong config db_import kong.yml`. This will load the data into the new cluster. +5. Gradually divert traffic away from your old nodes, and into + your 2.2.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +6. When your traffic is fully migrated to the 2.2.0 cluster, + decommission your old nodes. + +##### Installing 2.2.0 on a Fresh Datastore + +The following commands should be used to prepare a new 2.2.0 cluster from a +fresh datastore. By default the `kong` CLI tool will load the configuration +from `/etc/kong/kong.conf`, but you can optionally use the flag `-c` to +indicate the path to your configuration file: + +``` +$ kong migrations bootstrap [-c /path/to/your/kong.conf] +$ kong start [-c /path/to/your/kong.conf] +``` + +## Upgrade to `2.1.0` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different depending on which previous version from which you are migrating. + +If you are migrating from 2.0.0, upgrading into 2.1.x is a minor upgrade, +but read below for important instructions on database migration, especially +for Cassandra users. + +If you are migrating from 1.x, upgrading into 2.1.x is a major upgrade, +so, in addition, be aware of any [breaking changes](#breaking-changes-2.0.0) +between the 1.x and 2.x series below, further detailed in the +[CHANGELOG.md](https://github.com/Kong/kong/blob/2.0.0/CHANGELOG.md) document. + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +for the gateway are bundled and you can skip this section. + +If you are building your dependencies by hand, there are changes since the +previous release, so you will need to rebuild them with the latest patches. + +In order to use all Kong features, including the new +dynamic upstream keepalive behavior, the required OpenResty version is +[1.15.8.3](http://openresty.org/en/changelog-1015008.html) and the +the set of [OpenResty +patches](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools/openresty-patches) +included has changed, including the latest release of +[lua-kong-nginx-module](https://github.com/Kong/lua-kong-nginx-module). +The [kong-build-tools](https://github.com/Kong/kong-build-tools) +repository contains [openresty-build-tools](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools), +which allows you to build OpenResty with the necessary patches +and modules easily. + +For Go support, you also need to build both your plugins and +the [Kong go-pluginserver](https://github.com/kong/go-pluginserver). +The documentation includes detailed [instructions on how to build +the plugin server and your plugins](https://docs.konghq.com/2.1.x/go/). + +#### 2. Template Changes + +The **Nginx configuration file has changed**, which means that you need to +update it if you are using a custom template. + +To view the configuration changes between 2.0.0 and 2.1.0, clone the +[Kong repository](https://github.com/kong/kong) and run `git diff` +on the configuration templates, using `-w` for greater readability: + +``` +git clone https://github.com/kong/kong +cd kong +git diff -w 2.0.0 2.1.0 kong/templates/nginx_kong*.lua +``` + +To produce a patch file, use the following command: + +``` +git diff 2.0.0 2.1.0 kong/templates/nginx_kong*.lua > kong_config_changes.diff +``` + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `2.1.0` + +The lowest version that Kong 2.1.0 supports migrating from is 1.0.0. +If you are migrating from a version lower than 0.14.1, you need to +migrate to 0.14.1 first. Then, once you are migrating from 0.14.1, +please migrate to 1.5.0 first. + +The steps for upgrading from 0.14.1 to 1.5.0 are the same as upgrading +from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path), with the addition of the `kong +migrations migrate-apis` command, which you can use to migrate legacy +`apis` configurations. + +Once you migrated to 1.5.0, you can follow the instructions in the section +below to migrate to 2.1.0. + +##### Upgrade from `1.0.0` - `2.0.0` to `2.1.0` + +**Postgres** + +Kong 2.1.0 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that the new version of Kong is able to use +the database as it is migrated while the old Kong cluster keeps working until +it is time to decommission it. For this reason, the migration is split into +two steps, performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 2.1.0). + +1. Download 2.1.0, and configure it to point to the same datastore + as your old (1.0 to 2.0) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old (pre-2.1) and new (2.1.0) + clusters can now run simultaneously. Start provisioning 2.1.0 nodes, + but do not use their Admin API yet. If you need to perform Admin API + requests, these should be made to the old cluster's nodes. The reason + is to prevent the new cluster from generating data that is not understood + by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 2.1.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 2.1.0 cluster, + decommission your old nodes. +5. From your 2.1.0 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 2.1.0 nodes. + +**Cassandra** + +Due to internal changes, the table schemas used by Kong 2.1.0 on Cassandra +are incompatible with those used by Kong 2.0.0. Migrating using the usual commands +`kong migrations up` and `kong migrations finish` will require a small +window of downtime, since the old and new versions cannot use the +database at the same time. Alternatively, to keep your previous version fully +operational while the new one initializes, you will need to transfer the +data to a new keyspace via a database dump, as described below: + +1. Download 2.1.0, and configure it to point to a new keyspace. + Run `kong migrations bootstrap`. +2. Once that finishes running, both the old (pre-2.1) and new (2.1.0) + clusters can now run simultaneously, but the new cluster does not + have any data yet. +3. On the old cluster, run `kong config db_export`. This will create + a file `kong.yml` with a database dump. +4. Transfer the file to the new cluster and run + `kong config db_import kong.yml`. This will load the data into the new cluster. +5. Gradually divert traffic away from your old nodes, and into + your 2.1.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +6. When your traffic is fully migrated to the 2.1.0 cluster, + decommission your old nodes. + +##### Installing 2.1.0 on a Fresh Datastore + +The following commands should be used to prepare a new 2.1.0 cluster from a +fresh datastore. By default the `kong` CLI tool will load the configuration +from `/etc/kong/kong.conf`, but you can optionally use the flag `-c` to +indicate the path to your configuration file: + +``` +$ kong migrations bootstrap [-c /path/to/your/kong.conf] +$ kong start [-c /path/to/your/kong.conf] +``` + + +## Upgrade to `2.0.0` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different on which previous version from which you are migrating. +Upgrading into 2.0.x is a major version upgrade, so be aware of any +breaking changes listed in the [CHANGELOG.md](https://github.com/Kong/kong/blob/2.0.0/CHANGELOG.md) document. + + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +are bundled and you can skip this section. + +If you are building your dependencies by hand, there are changes since the +previous release, so you will need to rebuild them with the latest patches. + +The required OpenResty version is +[1.15.8.2](http://openresty.org/en/changelog-1015008.html), and the +the set of [OpenResty +patches](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools/openresty-patches) +included has changed, including the latest release of +[lua-kong-nginx-module](https://github.com/Kong/lua-kong-nginx-module). +Our [kong-build-tools](https://github.com/Kong/kong-build-tools) +repository allows you to build OpenResty with the necessary patches +and modules easily. + +For Go support, you also need the [Kong go-pluginserver](https://github.com/kong/go-pluginserver). +This is bundled with Kong binary packages and it is automatically started by +Kong if Go plugin support is enabled in Kong's configuration. +Note that the Go version used to compile any Go plugins needs to match the Go +version of the `go-pluginserver`. You can check the Go version used to +build the `go-pluginserver` binary running `go-pluginserver -version`. + + +#### 2. Breaking Changes + +Kong 2.0.0 does include a few breaking changes over Kong 1.x, all of them +related to the removal of service mesh: + +- **Removed Service Mesh support** - That has been deprecated in Kong 1.4 + and made off-by-default already, and the code is now be gone in 2.0. + For Service Mesh, we now have [Kuma](https://kuma.io), which is something + designed for Mesh patterns from day one, so we feel at peace with removing + Kong's native Service Mesh functionality and focus on its core capabilities + as a gateway. +- As part of service mesh removal, serviceless proxying was removed. + You can still set `service = null` when creating a route for use with + serverless plugins such as `aws-lambda`, or `request-termination`. +- Removed the `origins` property. +- Removed the `transparent` property. +- Removed the Sidecar Injector plugin which was used for service mesh. +- The **Nginx configuration file has changed**, which means that you need to update + it if you are using a custom template. Changes were made to improve + stream mode support and to make the Nginx injections system more + powerful so that custom templates are less of a necessity. The changes + are detailed in a diff included below. + - :warning: Note that the `kong_cache` shm was split into two + shms: `kong_core_cache` and `kong_cache`. If you are using a + custom Nginx template, make sure core cache shared dictionaries + are defined, including db-less mode shadow definitions. + Both cache values rely on the already existent `mem_cache_size` + configuration option to set their size, so when upgrading from + a previous Kong version, the cache memory consumption might + double if this value is not adjusted. + +
+Click here to see the Nginx configuration changes +

+ +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index 5c6c1db03..6b4b4a818 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -5,52 +5,46 @@ server_tokens off; + > if anonymous_reports then + ${{SYSLOG_REPORTS}} + > end +- + error_log ${{PROXY_ERROR_LOG}} ${{LOG_LEVEL}}; + +-> if nginx_optimizations then +->-- send_timeout 60s; # default value +->-- keepalive_timeout 75s; # default value +->-- client_body_timeout 60s; # default value +->-- client_header_timeout 60s; # default value +->-- tcp_nopush on; # disabled until benchmarked +->-- proxy_buffer_size 128k; # disabled until benchmarked +->-- proxy_buffers 4 256k; # disabled until benchmarked +->-- proxy_busy_buffers_size 256k; # disabled until benchmarked +->-- reset_timedout_connection on; # disabled until benchmarked +-> end +- +-client_max_body_size ${{CLIENT_MAX_BODY_SIZE}}; +-proxy_ssl_server_name on; +-underscores_in_headers on; +- + lua_package_path '${{LUA_PACKAGE_PATH}};;'; + lua_package_cpath '${{LUA_PACKAGE_CPATH}};;'; + lua_socket_pool_size ${{LUA_SOCKET_POOL_SIZE}}; ++lua_socket_log_errors off; + lua_max_running_timers 4096; + lua_max_pending_timers 16384; ++lua_ssl_verify_depth ${{LUA_SSL_VERIFY_DEPTH}}; ++> if lua_ssl_trusted_certificate then ++lua_ssl_trusted_certificate '${{LUA_SSL_TRUSTED_CERTIFICATE}}'; ++> end ++ + lua_shared_dict kong 5m; ++lua_shared_dict kong_locks 8m; ++lua_shared_dict kong_healthchecks 5m; ++lua_shared_dict kong_process_events 5m; ++lua_shared_dict kong_cluster_events 5m; ++lua_shared_dict kong_rate_limiting_counters 12m; ++lua_shared_dict kong_core_db_cache ${{MEM_CACHE_SIZE}}; ++lua_shared_dict kong_core_db_cache_miss 12m; + lua_shared_dict kong_db_cache ${{MEM_CACHE_SIZE}}; +-> if database == "off" then +-lua_shared_dict kong_db_cache_2 ${{MEM_CACHE_SIZE}}; +-> end + lua_shared_dict kong_db_cache_miss 12m; + > if database == "off" then ++lua_shared_dict kong_core_db_cache_2 ${{MEM_CACHE_SIZE}}; ++lua_shared_dict kong_core_db_cache_miss_2 12m; ++lua_shared_dict kong_db_cache_2 ${{MEM_CACHE_SIZE}}; + lua_shared_dict kong_db_cache_miss_2 12m; + > end +-lua_shared_dict kong_locks 8m; +-lua_shared_dict kong_process_events 5m; +-lua_shared_dict kong_cluster_events 5m; +-lua_shared_dict kong_healthchecks 5m; +-lua_shared_dict kong_rate_limiting_counters 12m; + > if database == "cassandra" then + lua_shared_dict kong_cassandra 5m; + > end +-lua_socket_log_errors off; +-> if lua_ssl_trusted_certificate then +-lua_ssl_trusted_certificate '${{LUA_SSL_TRUSTED_CERTIFICATE}}'; ++> if role == "control_plane" then ++lua_shared_dict kong_clustering 5m; ++> end ++ ++underscores_in_headers on; ++> if ssl_ciphers then ++ssl_ciphers ${{SSL_CIPHERS}}; + > end +-lua_ssl_verify_depth ${{LUA_SSL_VERIFY_DEPTH}}; + + # injected nginx_http_* directives + > for _, el in ipairs(nginx_http_directives) do +@@ -66,61 +60,47 @@ init_worker_by_lua_block { + Kong.init_worker() + } + +- +-> if #proxy_listeners > 0 then ++> if (role == "traditional" or role == "data_plane") and #proxy_listeners > 0 then + upstream kong_upstream { + server 0.0.0.1; + balancer_by_lua_block { + Kong.balancer() + } + +-# injected nginx_http_upstream_* directives +-> for _, el in ipairs(nginx_http_upstream_directives) do ++ # injected nginx_upstream_* directives ++> for _, el in ipairs(nginx_upstream_directives) do + $(el.name) $(el.value); + > end + } + + server { + server_name kong; +-> for i = 1, #proxy_listeners do +- listen $(proxy_listeners[i].listener); ++> for _, entry in ipairs(proxy_listeners) do ++ listen $(entry.listener); + > end ++ + error_page 400 404 408 411 412 413 414 417 494 /kong_error_handler; + error_page 500 502 503 504 /kong_error_handler; + + access_log ${{PROXY_ACCESS_LOG}}; + error_log ${{PROXY_ERROR_LOG}} ${{LOG_LEVEL}}; + +- client_body_buffer_size ${{CLIENT_BODY_BUFFER_SIZE}}; +- + > if proxy_ssl_enabled then + ssl_certificate ${{SSL_CERT}}; + ssl_certificate_key ${{SSL_CERT_KEY}}; ++ ssl_session_cache shared:SSL:10m; + ssl_certificate_by_lua_block { + Kong.ssl_certificate() + } +- +- ssl_session_cache shared:SSL:10m; +- ssl_session_timeout 10m; +- ssl_prefer_server_ciphers on; +- ssl_ciphers ${{SSL_CIPHERS}}; +-> end +- +-> if client_ssl then +- proxy_ssl_certificate ${{CLIENT_SSL_CERT}}; +- proxy_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}}; +-> end +- +- real_ip_header ${{REAL_IP_HEADER}}; +- real_ip_recursive ${{REAL_IP_RECURSIVE}}; +-> for i = 1, #trusted_ips do +- set_real_ip_from $(trusted_ips[i]); + > end + + # injected nginx_proxy_* directives + > for _, el in ipairs(nginx_proxy_directives) do + $(el.name) $(el.value); + > end ++> for i = 1, #trusted_ips do ++ set_real_ip_from $(trusted_ips[i]); ++> end + + rewrite_by_lua_block { + Kong.rewrite() +@@ -171,43 +151,93 @@ server { + proxy_pass_header Server; + proxy_pass_header Date; + proxy_ssl_name $upstream_host; ++ proxy_ssl_server_name on; ++> if client_ssl then ++ proxy_ssl_certificate ${{CLIENT_SSL_CERT}}; ++ proxy_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}}; ++> end + proxy_pass $upstream_scheme://kong_upstream$upstream_uri; + } + + location @grpc { + internal; ++ default_type ''; + set $kong_proxy_mode 'grpc'; + ++ grpc_set_header TE $upstream_te; + grpc_set_header Host $upstream_host; + grpc_set_header X-Forwarded-For $upstream_x_forwarded_for; + grpc_set_header X-Forwarded-Proto $upstream_x_forwarded_proto; + grpc_set_header X-Forwarded-Host $upstream_x_forwarded_host; + grpc_set_header X-Forwarded-Port $upstream_x_forwarded_port; + grpc_set_header X-Real-IP $remote_addr; +- ++ grpc_pass_header Server; ++ grpc_pass_header Date; + grpc_pass grpc://kong_upstream; + } + + location @grpcs { + internal; ++ default_type ''; + set $kong_proxy_mode 'grpc'; + ++ grpc_set_header TE $upstream_te; + grpc_set_header Host $upstream_host; + grpc_set_header X-Forwarded-For $upstream_x_forwarded_for; + grpc_set_header X-Forwarded-Proto $upstream_x_forwarded_proto; + grpc_set_header X-Forwarded-Host $upstream_x_forwarded_host; + grpc_set_header X-Forwarded-Port $upstream_x_forwarded_port; + grpc_set_header X-Real-IP $remote_addr; +- ++ grpc_pass_header Server; ++ grpc_pass_header Date; ++ grpc_ssl_name $upstream_host; ++ grpc_ssl_server_name on; ++> if client_ssl then ++ grpc_ssl_certificate ${{CLIENT_SSL_CERT}}; ++ grpc_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}}; ++> end + grpc_pass grpcs://kong_upstream; + } + ++ location = /kong_buffered_http { ++ internal; ++ default_type ''; ++ set $kong_proxy_mode 'http'; ++ ++ rewrite_by_lua_block {;} ++ access_by_lua_block {;} ++ header_filter_by_lua_block {;} ++ body_filter_by_lua_block {;} ++ log_by_lua_block {;} ++ ++ proxy_http_version 1.1; ++ proxy_set_header TE $upstream_te; ++ proxy_set_header Host $upstream_host; ++ proxy_set_header Upgrade $upstream_upgrade; ++ proxy_set_header Connection $upstream_connection; ++ proxy_set_header X-Forwarded-For $upstream_x_forwarded_for; ++ proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto; ++ proxy_set_header X-Forwarded-Host $upstream_x_forwarded_host; ++ proxy_set_header X-Forwarded-Port $upstream_x_forwarded_port; ++ proxy_set_header X-Real-IP $remote_addr; ++ proxy_pass_header Server; ++ proxy_pass_header Date; ++ proxy_ssl_name $upstream_host; ++ proxy_ssl_server_name on; ++> if client_ssl then ++ proxy_ssl_certificate ${{CLIENT_SSL_CERT}}; ++ proxy_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}}; ++> end ++ proxy_pass $upstream_scheme://kong_upstream$upstream_uri; ++ } ++ + location = /kong_error_handler { + internal; ++ default_type ''; ++ + uninitialized_variable_warn off; + + rewrite_by_lua_block {;} +- + access_by_lua_block {;} + + content_by_lua_block { +@@ -215,13 +245,13 @@ server { + } + } + } +-> end ++> end -- (role == "traditional" or role == "data_plane") and #proxy_listeners > 0 + +-> if #admin_listeners > 0 then ++> if (role == "control_plane" or role == "traditional") and #admin_listeners > 0 then + server { + server_name kong_admin; +-> for i = 1, #admin_listeners do +- listen $(admin_listeners[i].listener); ++> for _, entry in ipairs(admin_listeners) do ++ listen $(entry.listener); + > end + + access_log ${{ADMIN_ACCESS_LOG}}; +@@ -233,11 +263,7 @@ server { + > if admin_ssl_enabled then + ssl_certificate ${{ADMIN_SSL_CERT}}; + ssl_certificate_key ${{ADMIN_SSL_CERT_KEY}}; +- +- ssl_session_cache shared:SSL:10m; +- ssl_session_timeout 10m; +- ssl_prefer_server_ciphers on; +- ssl_ciphers ${{SSL_CIPHERS}}; ++ ssl_session_cache shared:AdminSSL:10m; + > end + + # injected nginx_admin_* directives +@@ -265,20 +291,20 @@ server { + return 200 'User-agent: *\nDisallow: /'; + } + } +-> end ++> end -- (role == "control_plane" or role == "traditional") and #admin_listeners > 0 + + > if #status_listeners > 0 then + server { + server_name kong_status; +-> for i = 1, #status_listeners do +- listen $(status_listeners[i].listener); ++> for _, entry in ipairs(status_listeners) do ++ listen $(entry.listener); + > end + + access_log ${{STATUS_ACCESS_LOG}}; + error_log ${{STATUS_ERROR_LOG}} ${{LOG_LEVEL}}; + +- # injected nginx_http_status_* directives +-> for _, el in ipairs(nginx_http_status_directives) do ++ # injected nginx_status_* directives ++> for _, el in ipairs(nginx_status_directives) do + $(el.name) $(el.value); + > end + +@@ -303,4 +329,26 @@ server { + } + } + > end ++ ++> if role == "control_plane" then ++server { ++ server_name kong_cluster_listener; ++> for _, entry in ipairs(cluster_listeners) do ++ listen $(entry.listener) ssl; ++> end ++ ++ access_log off; ++ ++ ssl_verify_client optional_no_ca; ++ ssl_certificate ${{CLUSTER_CERT}}; ++ ssl_certificate_key ${{CLUSTER_CERT_KEY}}; ++ ssl_session_cache shared:ClusterSSL:10m; ++ ++ location = /v1/outlet { ++ content_by_lua_block { ++ Kong.serve_cluster_listener() ++ } ++ } ++} ++> end -- role == "control_plane" + ]] +``` + +

+
+ + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `2.0.0` + +The lowest version that Kong 2.0.0 supports migrating from is 1.0.0. +If you are migrating from a version lower than 0.14.1, you need to +migrate to 0.14.1 first. Then, once you are migrating from 0.14.1, +please migrate to 1.5.0 first. + +The steps for upgrading from 0.14.1 to 1.5.0 are the same as upgrading +from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path), with the addition of the `kong +migrations migrate-apis` command, which you can use to migrate legacy +`apis` configurations. + +Once you migrated to 1.5.0, you can follow the instructions in the section +below to migrate to 2.0.0. + +##### Upgrade from `1.0.0` - `1.5.0` to `2.0.0` + +Kong 2.0.0 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 2.0.0). + +1. Download 2.0.0, and configure it to point to the same datastore + as your old (1.0 to 1.5) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old and new (2.0.0) clusters can now + run simultaneously on the same datastore. Start provisioning + 2.0.0 nodes, but do not use their Admin API yet. If you need to + perform Admin API requests, these should be made to the old cluster's nodes. + The reason is to prevent the new cluster from generating data + that is not understood by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 2.0.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 2.0.0 cluster, + decommission your old nodes. +5. From your 2.0.0 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 2.0.0 nodes. + +##### Installing 2.0.0 on a Fresh Datastore + +The following commands should be used to prepare a new 2.0.0 cluster from a +fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + + +## Upgrade to `1.5.0` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different on which previous version from which you are migrating. +If you are upgrading from 0.x, this is a major upgrade. If you are +upgrading from 1.0.x or 1.4.x, this is a minor upgrade. Both scenarios are +explained below. + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +are bundled. If you are building your dependencies by hand, since Kong 1.4.0 the +only dependency upgraded is +[lua-resty-healthcheck](https://github.com/Kong/lua-resty-healthcheck) that must +be at least the 1.1.2 version from now on. For any lower version you should +check the upgrade path for the correct dependencies. + +#### 2. Breaking Changes + +Kong 1.5.0 does not include any breaking changes over Kong 1.4, but Kong 1.3 +included breaking changes in configuration and for routing in some edge-cases +over Kong 1.2, and Kong 1.0 included a number of breaking changes over Kong 0.x. +If you are upgrading from 1.2, please read the section on +[Kong 1.3 Breaking Changes](#kong-1-3-breaking-changes) carefully before +proceeding. If you are upgrading from 0.14,x, please read the section on +[Kong 1.0 Breaking Changes](#kong-1-0-breaking-changes) carefully before +proceeding. + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `1.5.0` + +The lowest version that Kong 1.5.0 supports migrating from is 0.14.1. if you +are migrating from a previous 0.x release, please migrate to 0.14.1 first. + +For upgrading from 0.14.1 to Kong 1.5.0, the steps for upgrading are the same +as upgrading from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path). + +##### Upgrade from `1.0.x` - `1.4.x` to `1.5.0` + +Kong 1.5.0 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 1.5.0). + +1. Download 1.5.0, and configure it to point to the same datastore + as your old (1.0 to 1.4) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old and new (1.5.0) clusters can now + run simultaneously on the same datastore. Start provisioning + 1.5.0 nodes, but do not use their Admin API yet. If you need to + perform Admin API requests, these should be made to the old cluster's nodes. + The reason is to prevent the new cluster from generating data + that is not understood by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 1.5.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 1.5.0 cluster, + decommission your old nodes. +5. From your 1.5.0 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 1.5.0 nodes. + +##### Installing 1.5.0 on a Fresh Datastore + +The following commands should be used to prepare a new 1.5.0 cluster from a +fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + + +## Upgrade to `1.4.0` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different on which previous version from which you are migrating. +If you are upgrading from 0.x, this is a major upgrade. If you are +upgrading from 1.0.x or 1.3.x, this is a minor upgrade. Both scenarios are +explained below. + + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +are bundled. If you are building your dependencies by hand, there are no changes +in dependencies from 1.3.0, for any lower version you should check the upgrade +path for the correct dependencies. + +#### 2. Breaking Changes + +Kong 1.4.0 does not include any breaking changes over Kong 1.3, but Kong 1.3 +included breaking changes in configuration and for routing in some edge-cases +over Kong 1.2, and Kong 1.0 included a number of breaking changes over Kong 0.x. +If you are upgrading from 1.2, please read the section on +[Kong 1.3 Breaking Changes](#kong-1-3-breaking-changes) carefully before +proceeding. If you are upgrading from 0.14,x, please read the section on +[Kong 1.0 Breaking Changes](#kong-1-0-breaking-changes) carefully before +proceeding. + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `1.4.0` + +The lowest version that Kong 1.4.0 supports migrating from is 0.14.1. if you +are migrating from a previous 0.x release, please migrate to 0.14.1 first. + +For upgrading from 0.14.1 to Kong 1.4.0, the steps for upgrading are the same +as upgrading from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path). + +##### Upgrade from `1.0.x` - `1.3.x` to `1.4.0` + +Kong 1.4.0 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 1.4.0). + +1. Download 1.4.0, and configure it to point to the same datastore + as your old (1.0 to 1.3) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old and new (1.4.0) clusters can now + run simultaneously on the same datastore. Start provisioning + 1.4.0 nodes, but do not use their Admin API yet. If you need to + perform Admin API requests, these should be made to the old cluster's nodes. + The reason is to prevent the new cluster from generating data + that is not understood by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 1.4.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 1.4.0 cluster, + decommission your old nodes. +5. From your 1.4.0 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 1.4.0 nodes. + +##### Installing 1.4.0 on a Fresh Datastore + +The following commands should be used to prepare a new 1.4.0 cluster from a +fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + +## Upgrade to `1.3` + +#### 1. Breaking Changes + +##### Dependencies + +If you are using the provided binary packages, all necessary dependencies +are bundled. If you are building your dependencies by hand, you should +be aware of the following changes: + +- The required OpenResty version has been bumped to + [1.15.8.1](http://openresty.org/en/changelog-1015008.html). If you are + installing Kong from one of our distribution packages, you are not affected + by this change. +- From this version on, the new + [lua-kong-nginx-module](https://github.com/Kong/lua-kong-nginx-module) Nginx + module is **required** to be built into OpenResty for Kong to function + properly. If you are installing Kong from one of our distribution packages, + you are not affected by this change. + [openresty-build-tools#26](https://github.com/Kong/openresty-build-tools/pull/26) + +**Note:** if you are not using one of our distribution packages and compiling +OpenResty from source, you must still apply Kong's [OpenResty +patches](https://github.com/kong/openresty-patches) (and, as highlighted above, +compile OpenResty with the new lua-kong-nginx-module). Our new +[openresty-build-tools](https://github.com/Kong/openresty-build-tools) +repository will allow you to do both easily. + +##### Core + +- Bugfixes in the router *may, in some edge-cases*, result in different Routes + being matched. It was reported to us that the router behaved incorrectly in + some cases when configuring wildcard Hosts and regex paths (e.g. + [#3094](https://github.com/Kong/kong/issues/3094)). It may be so that you are + subject to these bugs without realizing it. Please ensure that wildcard Hosts + and regex paths Routes you have configured are matching as expected before + upgrading. + [9ca4dc0](https://github.com/Kong/kong/commit/9ca4dc09fdb12b340531be8e0f9d1560c48664d5) + [2683b86](https://github.com/Kong/kong/commit/2683b86c2f7680238e3fe85da224d6f077e3425d) + [6a03e1b](https://github.com/Kong/kong/commit/6a03e1bd95594716167ccac840ff3e892ed66215) +- Upstream connections are now only kept-alive for 100 requests or 60 seconds + (idle) by default. Previously, upstream connections were not actively closed + by Kong. This is a (non-breaking) change in behavior inherited from Nginx + 1.15, and configurable via new configuration properties. + +##### Configuration + +- The `upstream_keepalive` configuration property is deprecated, and replaced + by the new `nginx_http_upstream_keepalive` property. Its behavior is almost + identical, but the notable difference is that the latter leverages the + [injected Nginx + directives](https://konghq.com/blog/kong-ce-nginx-injected-directives/) + feature added in Kong 0.14.0. +- The Nginx configuration file has changed, which means that you need to update + it if you are using a custom template. Changes were made to address the + `upstream_keepalive` change, the new gRPC support, and to make `ssl_protocols` + load via injected directives. The changes are detailed in a diff + included below. + +
+Click here to see the Nginx configuration changes +

+ +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index 761376a07..5a957a1b7 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -72,8 +72,10 @@ upstream kong_upstream { + balancer_by_lua_block { + Kong.balancer() + } +-> if upstream_keepalive > 0 then +- keepalive ${{UPSTREAM_KEEPALIVE}}; ++ ++# injected nginx_http_upstream_* directives ++> for _, el in ipairs(nginx_http_upstream_directives) do ++ $(el.name) $(el.value); + > end + } + +@@ -93,7 +95,6 @@ server { + > if proxy_ssl_enabled then + ssl_certificate ${{SSL_CERT}}; + ssl_certificate_key ${{SSL_CERT_KEY}}; +- ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_certificate_by_lua_block { + Kong.ssl_certificate() + } +@@ -120,6 +121,26 @@ server { + $(el.name) $(el.value); + > end + ++ rewrite_by_lua_block { ++ Kong.rewrite() ++ } ++ ++ access_by_lua_block { ++ Kong.access() ++ } ++ ++ header_filter_by_lua_block { ++ Kong.header_filter() ++ } ++ ++ body_filter_by_lua_block { ++ Kong.body_filter() ++ } ++ ++ log_by_lua_block { ++ Kong.log() ++ } ++ + location / { + default_type ''; + +@@ -134,14 +155,7 @@ server { + set $upstream_x_forwarded_proto ''; + set $upstream_x_forwarded_host ''; + set $upstream_x_forwarded_port ''; +- +- rewrite_by_lua_block { +- Kong.rewrite() +- } +- +- access_by_lua_block { +- Kong.access() +- } ++ set $kong_proxy_mode 'http'; + + proxy_http_version 1.1; + proxy_set_header TE $upstream_te; +@@ -157,38 +171,32 @@ server { + proxy_pass_header Date; + proxy_ssl_name $upstream_host; + proxy_pass $upstream_scheme://kong_upstream$upstream_uri; ++ } + +- header_filter_by_lua_block { +- Kong.header_filter() +- } ++ location @grpc { ++ internal; + +- body_filter_by_lua_block { +- Kong.body_filter() +- } ++ set $kong_proxy_mode 'grpc'; ++ grpc_pass grpc://kong_upstream; ++ } + +- log_by_lua_block { +- Kong.log() +- } ++ location @grpcs { ++ internal; ++ ++ set $kong_proxy_mode 'grpcs'; ++ grpc_pass grpcs://kong_upstream; + } + + location = /kong_error_handler { + internal; + uninitialized_variable_warn off; + +- content_by_lua_block { +- Kong.handle_error() +- } +- +- header_filter_by_lua_block { +- Kong.header_filter() +- } ++ rewrite_by_lua_block {;} + +- body_filter_by_lua_block { +- Kong.body_filter() +- } ++ access_by_lua_block {;} + +- log_by_lua_block { +- Kong.log() ++ content_by_lua_block { ++ Kong.handle_error() + } + } + } +@@ -210,7 +218,6 @@ server { + > if admin_ssl_enabled then + ssl_certificate ${{ADMIN_SSL_CERT}}; + ssl_certificate_key ${{ADMIN_SSL_CERT_KEY}}; +- ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; +``` + +

+
+ +#### 2. Suggested Upgrade Path + +##### Upgrade from `0.x` to `1.3` + +The lowest version that Kong 1.3 supports migrating from is 0.14.1. if you +are migrating from a previous 0.x release, please migrate to 0.14.1 first. + +For upgrading from 0.14.1 to Kong 1.3, the steps for upgrading are the same as +upgrading from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path). + +##### Upgrade from `1.0.x` - `1.2.x` to `1.3` + +Kong 1.3 supports the no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 1.2). + +1. Download 1.3, and configure it to point to the same datastore as your old + (1.0 - 1.2) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old and new (1.3) clusters can now run + simultaneously on the same datastore. Start provisioning 1.3 nodes, but do + not use their Admin API yet. If you need to perform Admin API requests, + these should be made to the old cluster's nodes. The reason is to prevent + the new cluster from generating data that is not understood by the old + cluster. +3. Gradually divert traffic away from your old nodes, and into + your 1.3 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 1.3 cluster, decommission your + old nodes. +5. From your 1.3 cluster, run: `kong migrations finish`. From this point on, + it will not be possible to start nodes in the old cluster pointing to the + same datastore anymore. Only run this command when you are confident that + your migration was successful. From now on, you can safely make Admin API + requests to your 1.3 nodes. + +##### Installing 1.3 on a Fresh Datastore + +The following commands should be used to prepare a new 1.3 cluster from a fresh +datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + + + +## Upgrade to `1.2` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different on which previous version from which you are migrating. +If you are upgrading from 0.x, this is a major upgrade. If you are +upgrading from 1.0.x or 1.1.x, this is a minor upgrade. Both scenarios are +explained below. + + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +are bundled. If you are building your dependencies by hand, you should +be aware of the following changes: + +- The required OpenResty version is 1.13.6.2, but for a full feature set, + including stream routing and service mesh abilities with mutual TLS, you need + Kong's [openresty-patches](https://github.com/kong/openresty-patches). + Note that the set of patches was updated from 1.0 to 1.2. +- The minimum required OpenSSL version is 1.1.1. If you are building by hand, + make sure all dependencies, including LuaRocks modules, are compiled using + the same OpenSSL version. If you are installing Kong from one of our + distribution packages, you are not affected by this change. + +#### 2. Breaking Changes + +Kong 1.2 does not include any breaking changes over Kong 1.0 or 1.1, but Kong 1.0 +included a number of breaking changes over Kong 0.x. If you are upgrading +from 0.14,x, please read the section on +[Kong 1.0 Breaking Changes](#kong-1-0-breaking-changes) carefully before +proceeding. + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `1.2` + +The lowest version that Kong 1.2 supports migrating from is 0.14.1. if you +are migrating from a previous 0.x release, please migrate to 0.14.1 first. + +For upgrading from 0.14.1 to Kong 1.2, the steps for upgrading are the same as +upgrading from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path). + +##### Upgrade from `1.0.x` or `1.1.x` to `1.2` + +Kong 1.2 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 1.2). + +1. Download 1.2, and configure it to point to the same datastore + as your old (1.0 or 1.1) cluster. Run `kong migrations up`. +2. Once that finishes running, both the old and new (1.2) clusters can now + run simultaneously on the same datastore. Start provisioning + 1.2 nodes, but do not use their Admin API yet. If you need to + perform Admin API requests, these should be made to the old cluster's nodes. + The reason is to prevent the new cluster from generating data + that is not understood by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 1.2 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 1.2 cluster, + decommission your old nodes. +5. From your 1.2 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 1.2 nodes. + +##### Upgrade Path from 1.2 Release Candidates + +The process is the same as for upgrading from 1.0 listed above, but on step 1 +you should run `kong migrations up --force` instead. + +##### Installing 1.2 on a Fresh Datastore + +The following commands should be used to prepare a new 1.2 cluster from a fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + + +## Upgrade to `1.1` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different on which previous version from which you are migrating. +If you are upgrading from 0.x, this is a major upgrade. If you are +upgrading from 1.0.x, this is a minor upgrade. Both scenarios are +explained below. + + +#### 1. Dependencies + +If you are using the provided binary packages, all necessary dependencies +are bundled. If you are building your dependencies by hand, you should +be aware of the following changes: + +- The required OpenResty version is 1.13.6.2, but for a full feature set, + including stream routing and service mesh abilities with mutual TLS, you need + Kong's [openresty-patches](https://github.com/kong/openresty-patches). + Note that the set of patches was updated from 1.0 to 1.1. +- The minimum required OpenSSL version is 1.1.1. If you are building by hand, + make sure all dependencies, including LuaRocks modules, are compiled using + the same OpenSSL version. If you are installing Kong from one of our + distribution packages, you are not affected by this change. + +#### 2. Breaking Changes + +Kong 1.1 does not include any breaking changes over Kong 1.0, but Kong 1.0 +included a number of breaking changes over Kong 0.x. If you are upgrading +from 0.14,x, please read the section on +[Kong 1.0 Breaking Changes](#kong-1-0-breaking-changes) carefully before +proceeding. + +#### 3. Suggested Upgrade Path + +##### Upgrade from `0.x` to `1.1` + +The lowest version that Kong 1.1 supports migrating from is 0.14.1. if you +are migrating from a previous 0.x release, please migrate to 0.14.1 first. + +For upgrading from 0.14.1 to Kong 1.1, the steps for upgrading are the same as +upgrading from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the [Suggested Upgrade Path for Kong +1.0](#kong-1-0-upgrade-path). + +##### Upgrade from `1.0.x` to `1.1` + +Kong 1.1 supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 1.1). + +1. Download 1.1, and configure it to point to the same datastore + as your 1.0 cluster. Run `kong migrations up`. +2. Once that finishes running, both 1.0 and 1.1 clusters can now + run simultaneously on the same datastore. Start provisioning + 1.1 nodes, but do not use their Admin API yet. If you need to + perform Admin API requests, these should be made to your 1.0 nodes. + The reason is to prevent the new cluster from generating data + that is not understood by the old cluster. +3. Gradually divert traffic away from your 1.0 nodes, and into + your 1.1 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 1.1 cluster, + decommission your 1.0 nodes. +5. From your 1.1 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start 1.0 + nodes pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 1.1 nodes. + +##### Upgrade Path from 1.1 Release Candidates + +The process is the same as for upgrading from 1.0 listed above, but on step 1 +you should run `kong migrations up --force` instead. + +##### Installing 1.1 on a Fresh Datastore + +The following commands should be used to prepare a new 1.1 cluster from a fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + + +## Upgrading `1.0.x` patch releases + +If you are upgrading from another release in the 1.0.x series (e.g. from 1.0.0 +to 1.0.1), there are no migrations. Simply upgrade your Kong installation and +[reload](https://docs.konghq.com/1.0.x/cli/#kong-reload) Kong: + +```shell +$ kong reload [-c configuration_file] +``` + +If you are upgrading from 0.x, then read the following section for +detailed migration instructions. + +## Upgrade from `0.x` to `1.0.x` + +Kong 1.0 is a major upgrade, and includes a number of new features +as well as breaking changes. + +This version introduces **a new schema format for plugins**, **changes in +Admin API endpoints**, **database migrations**, **Nginx configuration +changes**, and **removed configuration properties**. + +In this release, the **API entity is removed**, along with its related +Admin API endpoints. + +This section will highlight breaking changes that you need to be aware of +before upgrading and will describe the recommended upgrade path. We recommend +that you consult the full [1.0.0 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a +complete list of changes and new features. + + +#### 1. Breaking Changes + +##### Dependencies + +- The required OpenResty version is 1.13.6.2, but for a full feature set, + including stream routing and service mesh abilities with mutual TLS, you need + Kong's [openresty-patches](https://github.com/kong/openresty-patches). +- The minimum required OpenSSL version is 1.1.1. If you are building by hand, + make sure all dependencies, including LuaRocks modules, are compiled using + the same OpenSSL version. If you are installing Kong from one of our + distribution packages, you are not affected by this change. + +##### Configuration + +- The `custom_plugins` directive is removed (deprecated since 0.14.0). + Use `plugins` instead, which you can use not only to enable + custom plugins, but also to disable bundled plugins. +- The default value for `cassandra_lb_policy` changed from `RoundRobin` + to `RequestRoundRobin`. +- The Nginx configuration file has changed, which means that you need to update + it if you are using a custom template. The changes are detailed in a diff + included below. + +
+Click here to see the Nginx configuration changes +

+ +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index d4e416bc..8f268ffd 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -66,7 +66,9 @@ upstream kong_upstream { + balancer_by_lua_block { + Kong.balancer() + } ++> if upstream_keepalive > 0 then + keepalive ${{UPSTREAM_KEEPALIVE}}; ++> end + } + + server { +@@ -85,7 +87,7 @@ server { + > if proxy_ssl_enabled then + ssl_certificate ${{SSL_CERT}}; + ssl_certificate_key ${{SSL_CERT_KEY}}; +- ssl_protocols TLSv1.1 TLSv1.2; ++ ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_certificate_by_lua_block { + Kong.ssl_certificate() + } +@@ -200,7 +202,7 @@ server { + > if admin_ssl_enabled then + ssl_certificate ${{ADMIN_SSL_CERT}}; + ssl_certificate_key ${{ADMIN_SSL_CERT_KEY}}; +- ssl_protocols TLSv1.1 TLSv1.2; ++ ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; +``` + +

+
+ +- Kong generates a new template file for stream routing, + `nginx-kong-stream.conf`, included in the `stream` block + of its top-level Nginx configuration file. If you use + a custom Nginx configuration and wish to use stream + routing, you can generate this file using `kong prepare`. + +##### Core + +- The **API** entity and related concepts such as the + `/apis` endpoint, are removed. These were deprecated since + 0.13.0. Instead, use **Routes** to configure your + endpoints and **Services** to configure your upstream + services. +- The old DAO implementation (`kong.dao`) is removed, + which includes the old schema validation library. This + has implications to plugin developers, listed below. + - The last remaining entities that were converted to + the new DAO implementation were Plugins, Upstreams + and Targets. This has implications to the Admin API, + listed below. + +##### Plugins + +Kong 1.0.0 marks the introduction of version 1.0.0 of +the Plugin Development Kit (PDK). No major changes are +made to the PDK compared to release 0.14, but some older +non-PDK functionality which was possibly used by custom +plugins is now removed. + +- Plugins now use the new schema format introduced by the + new DAO implementation, for both plugin schemas + (in `schema.lua`) and custom DAO entities (`daos.lua`). + To ease the transition of plugins, the plugin loader + in 1.0 includes a *best-effort* schema auto-translator + for `schema.lua`, which should be sufficient for many + plugins (in 1.0.0rc1, our bundled plugins used the + auto-translator; they now use the new format). + - If your plugin using the old format in `schema.lua` + fails to load, check the error logs for messages + produced by the auto-translator. If a field cannot + be auto-translated, you can make a gradual conversion + of the schema file by adding a `new_type` entry to + the field table translation of the format. See, + for example, the [key-auth schema in 1.0.0rc1](https://github.com/Kong/kong/blob/1.0.0rc1/kong/plugins/key-auth/schema.lua#L39-L54). + The `new_type` annotation is ignored by Kong 0.x. + - If your custom plugin uses custom DAO objects (i.e. + if it includes a `daos.lua` file), it needs to be + converted to the new format. Their code also needs + to be adjusted accordingly, replacing uses of + `singletons.dao` or `kong.dao` by `kong.db` (note + that this module exposes a different API from the + old DAO implementation). +- Some Kong modules that had their functionality replaced + by the PDK in 0.14.0 are now removed: + - `kong.tools.ip`: use `kong.ip` from the PDK instead. + - `kong.tools.public`: replaced by various functionalities + of the PDK. + - `kong.tools.responses`: use `kong.response.exit` from the PDK instead. You + might want to use `kong.log.err` to log internal server errors as well. +- The `kong.api.crud_helpers` module was removed. + Use `kong.api.endpoints` instead if you need to customize + the auto-generated endpoints. + +##### Admin API + +- With the removal of the API entity, the `/apis` endpoint + is removed; accordingly, other endpoints that accepted + `api_id` no longer do so. Use Routes and Services instead. +- All entity endpoints now use the new Admin API implementation. + This means their requests and responses now use the same + syntax, which was already in use in endpoints such as + `/routes` and `/services`. + - All endpoints now use the same syntax for + referencing other entities as `/routes` + (for example, `"service":{"id":"..."}` instead of + `"service_id":"..."`), both in requests and responses. + - This change affects `/plugins` as well as + plugin-specific endpoints. + - Array-typed values are not specified as a + comma-separated list anymore. It must be specified as a + JSON array or using the various formats supported by + the url-formencoded array notation of the new Admin API + implementation (`a[1]=x&a[2]=y`, `a[]=x&a[]=y`, + `a=x&a=y`). + - This change affects attributes of the `/upstreams` endpoint. + - Error responses for the updated endpoints use + the new standardized format. + - As a result of being moved to the new Admin API implementation, + all endpoints supporting `PUT` do so with proper semantics. + - See the [Admin API + reference](https://docs.konghq.com/1.0.x/admin-api) + for more details. + +#### 2. Deprecation Notices + +There are no deprecation notices in this release. + + +#### 3. Suggested Upgrade Path + +##### Preliminary Checks + +If your cluster is running a version lower than 0.14, you need to +upgrade to 0.14.1 first instead. Upgrading from a pre-0.14 cluster +straight to Kong 1.0 is **not** supported. + +If you still use the deprecated API entity to configure your endpoints and +upstream services (via `/apis`) instead of using Routes for endpoints (via +`/routes`) and Services for upstream services (via `/services`), now is the +time to do so. Kong 1.0 will refuse to run migrations if you have any entity +configured using `/apis` in your datastore. Create equivalent Routes and +Services and delete your APIs. (Note that Kong does not do this automatically +because the naive option of creating a Route and Service pair for each API +would miss the point of the improvements brought by Routes and Services; +the ideal mapping of Routes and Services depends on your microservice +architecture.) + +If you use additional plugins other than the ones bundled with Kong, +make sure they are compatible with Kong 1.0 prior to upgrading. +See the section above on Plugins for information on plugin compatibility. + +##### Migration Steps from 0.14 + +Kong 1.0 introduces a new, improved migrations framework. +It supports a no-downtime, Blue/Green migration model for upgrading +from 0.14.x. This means that while the migration is ongoing, you will +have two Kong clusters running, sharing the same database. The "Blue" cluster +is your existing cluster running 0.14.x, the "Green" cluster is the new one +running Kong 1.0. + +The migrations are designed so that there is no need to fully copy +the data, but this also means that they are designed in such a way so that +the new version of Kong is able to use the data as it is migrated, and to do +it in a way so that the old Kong cluster keeps working until it is finally +time to decommission it. For this reason, the full migration is now split into +two steps, which are performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 1.0). + +For a no-downtime migration from a 0.14 cluster to a 1.0 cluster, +we recommend the following sequence of steps: + +1. Download 1.0, and configure it to point to the same datastore + as your 0.14 cluster. Run `kong migrations up` from a Kong 1.0 + node. +2. Once that finishes running, both 0.14 and 1.0 clusters can now + run simultaneously on the same datastore. Start provisioning + 1.0 nodes, but do not use their Admin API yet. If you need to + perform Admin API requests, these should be made to your 0.14 nodes. + The reason is to prevent the new cluster from generating data + that is not understood by the old cluster. +3. Gradually divert traffic away from your 0.14 nodes, and into + your 1.0 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 1.0 cluster, + decommission your 0.14 nodes. +5. From your 1.0 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start 0.14 + nodes pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 1.0 nodes. + +##### Upgrade Path from 1.0 Release Candidates + +The process is the same as for upgrading for 0.14 listed above, but on step 1 you should run `kong migrations up --force` instead. + +##### Installing 1.0 on a Fresh Datastore + +For installing on a fresh datastore, Kong 1.0 introduces the `kong migrations bootstrap` command. The following commands can be run to prepare a new 1.0 cluster from a fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + + +## Upgrade to `0.15` + +This is the last release in the 0.x series, giving users one last chance to +upgrade while still using some of the options and concepts that were marked as +deprecated in Kong 0.x and were removed in Kong 1.0. Still, Kong 0.15 does +have a number of breaking changes related to functionality that has changed +since version 0.14. + +This version introduces **a new schema format for plugins**, **changes in +Admin API endpoints**, **database migrations** and **Nginx configuration +changes**. + +This section will highlight breaking changes that you need to be aware of +before upgrading and will describe the recommended upgrade path. We recommend +that you consult the full [0.15 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a +complete list of changes and new features. + +#### 1. Breaking Changes + +##### Dependencies + +- The required OpenResty version is 1.13.6.2, but for a full feature set, + including stream routing and service mesh abilities with mutual TLS, + you need Kong's [openresty-patches](https://github.com/kong/openresty-patches). + The minimum required OpenSSL version is 1.1.1. If you are building by + hand, make sure all dependencies, including LuaRocks modules, are + compiled using the same OpenSSL version. + If you are installing Kong from one of our distribution packages, you are not + affected by this change. + +##### Configuration + +- The default value for `cassandra_lb_policy` changed from `RoundRobin` + to `RequestRoundRobin`. +- The Nginx configuration file has changed, which means that you need to update + it if you are using a custom template. The changes are detailed in a diff + included below. + +
+Click here to see the Nginx configuration changes +

+ +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index d4e416bc..8f268ffd 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -66,7 +66,9 @@ upstream kong_upstream { + balancer_by_lua_block { + Kong.balancer() + } ++> if upstream_keepalive > 0 then + keepalive ${{UPSTREAM_KEEPALIVE}}; ++> end + } + + server { +@@ -85,7 +87,7 @@ server { + > if proxy_ssl_enabled then + ssl_certificate ${{SSL_CERT}}; + ssl_certificate_key ${{SSL_CERT_KEY}}; +- ssl_protocols TLSv1.1 TLSv1.2; ++ ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_certificate_by_lua_block { + Kong.ssl_certificate() + } +@@ -200,7 +202,7 @@ server { + > if admin_ssl_enabled then + ssl_certificate ${{ADMIN_SSL_CERT}}; + ssl_certificate_key ${{ADMIN_SSL_CERT_KEY}}; +- ssl_protocols TLSv1.1 TLSv1.2; ++ ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; +``` + +

+
+ +- Kong generates a new template file for stream routing, + `nginx-kong-stream.conf`, included in the `stream` block + of its top-level Nginx configuration file. If you use + a custom Nginx configuration and wish to use stream + routing, you can generate this file using `kong prepare`. + +##### Core + +- The old DAO implementation (`kong.dao`) is no longer + used by the Kong core, which includes the old schema + validation library. This has implications to plugin + developers, listed below. + - The last remaining entities that were converted to + the new DAO implementation were Plugins, Upstreams + and Targets. This has implications to the Admin API, + listed below. + +##### Plugins + +Kong 0.15 includes version 1.0.0 of the Plugin Development Kit (PDK). No major +changes are made to the PDK compared to release 0.14, but some older non-PDK +functionality which was possibly used by custom plugins is now removed. + +- Plugins now use the new schema format introduced by the + new DAO implementation, for both plugin schemas + (in `schema.lua`) and custom DAO entities (`daos.lua`). + To ease the transition of plugins, the plugin loader + in 0.15 includes a *best-effort* schema auto-translator + for `schema.lua`, which should be sufficient for many + plugins (in 1.0.0rc1, our bundled plugins used the + auto-translator; they now use the new format). + - If your plugin using the old format in `schema.lua` + fails to load, check the error logs for messages + produced by the auto-translator. If a field cannot + be auto-translated, you can make a gradual conversion + of the schema file by adding a `new_type` entry to + the field table translation of the format. See, + for example, the [key-auth schema in 1.0.0rc1](https://github.com/Kong/kong/blob/1.0.0rc1/kong/plugins/key-auth/schema.lua#L39-L54). + The `new_type` annotation is ignored by Kong 0.x. + - If your custom plugin uses custom DAO objects (i.e. + if it includes a `daos.lua` file), it needs to be + converted to the new format. Their code also needs + to be adjusted accordingly, replacing uses of + `singletons.dao` or `kong.dao` by `kong.db` (note + that this module exposes a different API from the + old DAO implementation). + +##### Admin API + +- All entity endpoints now use the new Admin API implementation. + This means their requests and responses now use the same + syntax, which was already in use in endpoints such as + `/routes` and `/services`. + - All endpoints now use the same syntax for + referencing other entities as `/routes` + (for example, `"service":{"id":"..."}` instead of + `"service_id":"..."`), both in requests and responses. + - This change affects `/plugins` as well as + plugin-specific endpoints. + - Array-typed values are not specified as a + comma-separated list anymore. It must be specified as a + JSON array or using the various formats supported by + the url-formencoded array notation of the new Admin API + implementation (`a[1]=x&a[2]=y`, `a[]=x&a[]=y`, + `a=x&a=y`). + - This change affects attributes of the `/upstreams` endpoint. + - Error responses for the updated endpoints use + the new standardized format. + - As a result of being moved to the new Admin API implementation, + all endpoints supporting `PUT` do so with proper semantics. + - See the [Admin API + reference](https://docs.konghq.com/0.15/admin-api) + for more details. + +#### 2. Deprecation Notices + +Kong 0.15 retains the deprecation notices of previous releases; all modules +and concepts that have been marked as deprecated in previous releases are +retained in 0.15 but are removed in 1.0. See the Kong 1.0 changelog and +upgrade path for a detailed list. + +#### 3. Suggested Upgrade Path + +##### Preliminary Checks + +If your cluster is running a version lower than 0.14, you need to +upgrade to 0.14.1 first instead. Upgrading from a pre-0.14 cluster +straight to Kong 0.15 is **not** supported. + +If you use additional plugins other than the ones bundled with Kong, +make sure they are compatible with Kong 0.15 prior to upgrading. +See the section above on Plugins for information on plugin compatibility. + +##### Migration Steps from 0.14 + +Kong 0.15 introduces a new, improved migrations framework. +It supports a no-downtime, Blue/Green migration model for upgrading +from 0.14.x. The full migration is now split into two steps, +which are performed via commands `kong migrations up` and +`kong migrations finish`. + +For a no-downtime migration from a 0.14 cluster to a 0.15 cluster, +we recommend the following sequence of steps: + +1. Download 0.15, and configure it to point to the same datastore + as your 0.14 cluster. Run `kong migrations up`. +2. Both 0.14 and 0.15 nodes can now run simultaneously on the same + datastore. Start provisioning 0.15 nodes, but do not use their + Admin API yet. Prefer making Admin API requests to your 0.14 nodes + instead. +3. Gradually divert traffic away from your 0.14 nodes, and into + your 0.15 cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 0.15 cluster, + decommission your 0.14 nodes. +5. From your 0.15 cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start 0.14 + nodes pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 0.15 nodes. + +##### Installing 0.15 on a Fresh Datastore + +For installing on a fresh datastore, Kong 0.15 introduces the `kong migrations +bootstrap` command. The following commands can be run to prepare a new 0.15 +cluster from a fresh datastore: + +``` +$ kong migrations bootstrap [-c config] +$ kong start [-c config] +``` + +## Upgrade to `0.14.x` + +This version introduces **changes in Admin API endpoints**, **database +migrations**, **Nginx configuration changes**, and **removed configuration +properties**. + +In this release, the **API entity is still supported**, along with its related +Admin API endpoints. + +This section will highlight breaking changes that you need to be aware of +before upgrading and will describe the recommended upgrade path. We recommend +that you consult the full [0.14.0 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a +complete list of changes and new features. + +#### 1. Breaking Changes + +##### Dependencies + +- The required OpenResty version has been bumped to 1.13.6.2. If you + are installing Kong from one of our distribution packages, you are not + affected by this change. +- Support for PostreSQL 9.4 (deprecated in 0.12.0) is now dropped. +- Support for Cassandra 2.1 (deprecated in 0.12.0) is now dropped. + +##### Configuration + +- The `server_tokens` and `latency_tokens` configuration properties have been + removed. Instead, a new `headers` configuration properties replaces them. + See the default configuration file or the [configuration + reference](https://docs.konghq.com/0.14.x/configuration/) for more details. +- The Nginx configuration file has changed, which means that you need to update + it if you are using a custom template. The changes are detailed in a diff + included below. + +##### Plugins +- The Runscope plugin has been dropped, based on the EoL announcement made by Runscope about their Traffic Inspector product. [#3495](https://github.com/Kong/kong/pull/3495) + +##### Admin API +- The SSL Certificates and SNI entities have moved to the new DAO implementation. As such, the /certificates and /snis endpoints have received notable usability improvements, but suffer from a few breaking changes. [#3386](https://github.com/Kong/kong/pull/3386) + +- The Consumers entity has moved to the new DAO implementation. As such, the `/consumers` endpoint has received notable usability improvements, but suffers from a few breaking changes. [#3437](https://github.com/Kong/kong/pull/3437) + +
+Click here to see the Nginx configuration changes +

+ +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index a66c230f..d4e416bc 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -29,8 +29,9 @@ lua_socket_pool_size ${{LUA_SOCKET_POOL_SIZE}}; + lua_max_running_timers 4096; + lua_max_pending_timers 16384; + lua_shared_dict kong 5m; +-lua_shared_dict kong_cache ${{MEM_CACHE_SIZE}}; ++lua_shared_dict kong_db_cache ${{MEM_CACHE_SIZE}}; + lua_shared_dict kong_db_cache_miss 12m; ++lua_shared_dict kong_locks 8m; + lua_shared_dict kong_process_events 5m; + lua_shared_dict kong_cluster_events 5m; + lua_shared_dict kong_healthchecks 5m; +@@ -44,13 +45,18 @@ lua_ssl_trusted_certificate '${{LUA_SSL_TRUSTED_CERTIFICATE}}'; + lua_ssl_verify_depth ${{LUA_SSL_VERIFY_DEPTH}}; + > end + ++# injected nginx_http_* directives ++> for _, el in ipairs(nginx_http_directives) do ++$(el.name) $(el.value); ++> end ++ + init_by_lua_block { +- kong = require 'kong' +- kong.init() ++ Kong = require 'kong' ++ Kong.init() + } + + init_worker_by_lua_block { +- kong.init_worker() ++ Kong.init_worker() + } + + +@@ -58,7 +64,7 @@ init_worker_by_lua_block { + upstream kong_upstream { + server 0.0.0.1; + balancer_by_lua_block { +- kong.balancer() ++ Kong.balancer() + } + keepalive ${{UPSTREAM_KEEPALIVE}}; + } +@@ -81,7 +87,7 @@ server { + ssl_certificate_key ${{SSL_CERT_KEY}}; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_certificate_by_lua_block { +- kong.ssl_certificate() ++ Kong.ssl_certificate() + } + + ssl_session_cache shared:SSL:10m; +@@ -101,7 +107,15 @@ server { + set_real_ip_from $(trusted_ips[i]); + > end + ++ # injected nginx_proxy_* directives ++> for _, el in ipairs(nginx_proxy_directives) do ++ $(el.name) $(el.value); ++> end ++ + location / { ++ default_type ''; ++ ++ set $ctx_ref ''; + set $upstream_host ''; + set $upstream_upgrade ''; + set $upstream_connection ''; +@@ -113,11 +127,11 @@ server { + set $upstream_x_forwarded_port ''; + + rewrite_by_lua_block { +- kong.rewrite() ++ Kong.rewrite() + } + + access_by_lua_block { +- kong.access() ++ Kong.access() + } + + proxy_http_version 1.1; +@@ -135,22 +149,36 @@ server { + proxy_pass $upstream_scheme://kong_upstream$upstream_uri; + + header_filter_by_lua_block { +- kong.header_filter() ++ Kong.header_filter() + } + + body_filter_by_lua_block { +- kong.body_filter() ++ Kong.body_filter() + } + + log_by_lua_block { +- kong.log() ++ Kong.log() + } + } + + location = /kong_error_handler { + internal; ++ uninitialized_variable_warn off; ++ + content_by_lua_block { +- kong.handle_error() ++ Kong.handle_error() ++ } ++ ++ header_filter_by_lua_block { ++ Kong.header_filter() ++ } ++ ++ body_filter_by_lua_block { ++ Kong.body_filter() ++ } ++ ++ log_by_lua_block { ++ Kong.log() + } + } + } +@@ -180,10 +208,15 @@ server { + ssl_ciphers ${{SSL_CIPHERS}}; + > end + ++ # injected nginx_admin_* directives ++> for _, el in ipairs(nginx_admin_directives) do ++ $(el.name) $(el.value); ++> end ++ + location / { + default_type application/json; + content_by_lua_block { +- kong.serve_admin_api() ++ Kong.serve_admin_api() + } + } +``` + +

+
+ +##### Core + +- If you are relying on passive health-checks to detect TCP timeouts, you + should double-check your health-check configurations. Previously, timeouts + were erroneously contributing to the `tcp_failures` counter. They are now + properly contributing to the `timeout` counter. In order to short-circuit + traffic based on timeouts, you must ensure that your `timeout` settings + are properly configured. See the [Health Checks + reference](https://docs.konghq.com/0.14.x/health-checks-circuit-breakers/) + for more details. + +##### Plugins + +- Custom plugins can now see their `header_filter`, `body_filter`, and `log` + phases executed without the `rewrite` or `access` phases running first. This + can happen when Nginx itself produces an error while parsing the client's + request. Similarly, `ngx.var` values (e.g. `ngx.var.request_uri`) may be + `nil`. Plugins should be hardened to handle such cases and avoid using + uninitialized variables, which could throw Lua errors. +- The Runscope plugin has been dropped, based on the EoL announcement made by + Runscope about their Traffic Inspector product. + +##### Admin API + +- As a result of being moved to the new Admin API implementation (and + supporting `PUT` and named endpoints), the `/snis` endpoint + `ssl_certificate_id` attribute has been renamed to `certificate_id`. + See the [Admin API + reference](https://docs.konghq.com/0.14.x/admin-api/#add-sni) for + more details. +- On the `/certificates` endpoint, the `snis` attribute is not specified as a + comma-separated list anymore. It must be specified as a JSON array or using + the url-formencoded array notation of other recent Admin API endpoints. See + the [Admin API + reference](https://docs.konghq.com/0.14.x/admin-api/#add-certificate) for + more details. +- Filtering by username in the `/consumers` endpoint is not supported with + `/consumers?username=...`. Instead, use `/consumers/{username}` to retrieve a + Consumer by its username. Filtering with `/consumers?custom_id=...` is still + supported. + +#### 2. Deprecation Notices + +- The `custom_plugins` configuration property is now deprecated in favor of + `plugins`. See the default configuration file or the [configuration + reference](https://docs.konghq.com/0.14.x/configuration/) for more details. + +#### 3. Suggested Upgrade Path + +You can now start migrating your cluster from `0.13.x` to `0.14`. If you are +doing this upgrade "in-place", against the datastore of a running 0.13 cluster, +then for a short period of time, your database schema won't be fully compatible +with your 0.13 nodes anymore. This is why we suggest either performing this +upgrade when your 0.13 cluster is warm and most entities are cached, or against +a new database, if you can migrate your data. If you wish to temporarily make +your APIs unavailable, you can leverage the +[request-termination](https://getkong.org/plugins/request-termination/) plugin. + +The path to upgrade a 0.13 datastore is identical to the one of previous major +releases: + +1. If you are planning on upgrading Kong while 0.13 nodes are running against + the same datastore, make sure those nodes are warm enough (they should have + most of your entities cached already), or temporarily disable your APIs. +2. Provision a 0.14 node and configure it as you wish (environment variables/ + configuration file). Make sure to point this new 0.14 node to your current + datastore. +3. **Without starting the 0.14 node**, run the 0.14 migrations against your + current datastore: + +``` +$ kong migrations up [-c kong.conf] +``` + +As usual, this step should be executed from a **single node**. + +4. You can now provision a fresh 0.14 cluster pointing to your migrated + datastore and start your 0.14 nodes. +5. Gradually switch your traffic from the 0.13 cluster to the new 0.14 cluster. + Remember, once your database is migrated, your 0.13 nodes will rely on + their cache and not on the underlying database. Your traffic should switch + to the new cluster as quickly as possible. +6. Once your traffic is fully migrated to the 0.14 cluster, decommission + your 0.13 cluster. + +You have now successfully upgraded your cluster to run 0.14 nodes exclusively. + +## Upgrade to `0.13.x` + +This version comes with **new model entities**, **database migrations**, and +**nginx configuration changes**. + +This section will only highlight the breaking changes that you need to be +aware of, and describe a recommended upgrade path. We recommend that you +consult the full [0.13.0 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a +complete list of changes and new features. + +See below the breaking changes section for a detailed list of steps recommended +to **run migrations** and upgrade from a previous version of Kong. + +#### 1. Breaking Changes + +- **Note to Docker users**: The `latest` tag on Docker Hub now points to the + **alpine** image instead of CentOS. This also applies to the `0.13.0` tag. + +##### Dependencies + +- Support for Cassandra 2.1 was deprecated in 0.12.0 and has been dropped + starting with 0.13.0. +- Various dependencies have been bumped. Once again, consult the Changelog for + a detailed list. + +##### Configuration + +- The `proxy_listen` and `admin_listen` configuration values have a new syntax. + See the configuration file or the [0.13.x + documentation](https://getkong.org/docs/0.13.x/configuration/) for insights + on the new syntax. +- The nginx configuration file has changed, which means that you need to update + it if you are using a custom template. The changes are detailed in a diff + included below. + +
+Click here to see the nginx configuration changes +

+ +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index 5639f319..62f5f1ae 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -51,6 +51,8 @@ init_worker_by_lua_block { + kong.init_worker() + } + ++ ++> if #proxy_listeners > 0 then + upstream kong_upstream { + server 0.0.0.1; + balancer_by_lua_block { +@@ -61,7 +63,9 @@ upstream kong_upstream { + + server { + server_name kong; +- listen ${{PROXY_LISTEN}}${{PROXY_PROTOCOL}}; ++> for i = 1, #proxy_listeners do ++ listen $(proxy_listeners[i].listener); ++> end + error_page 400 404 408 411 412 413 414 417 /kong_error_handler; + error_page 500 502 503 504 /kong_error_handler; + +@@ -70,8 +74,7 @@ server { + + client_body_buffer_size ${{CLIENT_BODY_BUFFER_SIZE}}; + +-> if ssl then +- listen ${{PROXY_LISTEN_SSL}} ssl${{HTTP2}}${{PROXY_PROTOCOL}}; ++> if proxy_ssl_enabled then + ssl_certificate ${{SSL_CERT}}; + ssl_certificate_key ${{SSL_CERT_KEY}}; + ssl_protocols TLSv1.1 TLSv1.2; +@@ -149,10 +152,14 @@ server { + } + } + } ++> end + ++> if #admin_listeners > 0 then + server { + server_name kong_admin; +- listen ${{ADMIN_LISTEN}}; ++> for i = 1, #admin_listeners do ++ listen $(admin_listeners[i].listener); ++> end + + access_log ${{ADMIN_ACCESS_LOG}}; + error_log ${{ADMIN_ERROR_LOG}} ${{LOG_LEVEL}}; +@@ -160,8 +167,7 @@ server { + client_max_body_size 10m; + client_body_buffer_size 10m; + +-> if admin_ssl then +- listen ${{ADMIN_LISTEN_SSL}} ssl${{ADMIN_HTTP2}}; ++> if admin_ssl_enabled then + ssl_certificate ${{ADMIN_SSL_CERT}}; + ssl_certificate_key ${{ADMIN_SSL_CERT_KEY}}; + ssl_protocols TLSv1.1 TLSv1.2; +@@ -189,4 +195,5 @@ server { + return 200 'User-agent: *\nDisallow: /'; + } + } ++> end +``` + +

+
+ +##### Plugins + +- The galileo plugin is considered deprecated and not enabled by default + anymore. It is still shipped with Kong 0.13.0, but you must enable it by + specifying it in the `custom_plugins` configuration property, like so: + `custom_plugins = galileo` (or via the `KONG_CUSTOM_PLUGINS` environment + variable). +- The migrations will remove and re-create the rate-limiting and + response-ratelimiting tables storing counters. This means that your counters + will reset. + +#### 2. Deprecation Notices + +Starting with 0.13.0, the "API" entity is considered **deprecated**. While +still supported, we will eventually remove the entity and its related endpoints +from the Admin API. Services and Routes are the new first-class citizen +entities that new users (or users upgrading their clusters) should configure. + +You can read more about Services and Routes in the [Proxy +Guide](https://getkong.org/docs/0.13.x/proxy/) and the [Admin API +Reference](https://getkong.org/docs/0.13.x/admin-api/). + +#### 3. Suggested Upgrade Path + +You can now start migrating your cluster from `0.12.x` to `0.13`. If you are +doing this upgrade "in-place", against the datastore of a running 0.12 cluster, +then for a short period of time, your database schema won't be fully compatible +with your 0.12 nodes anymore. This is why we suggest either performing this +upgrade when your 0.12 cluster is warm and most entities are cached, or against +a new database if you can migrate your data. If you wish to temporarily make +your APIs unavailable, you can leverage the +[request-termination](https://getkong.org/plugins/request-termination/) plugin. + +The path to upgrade a 0.12 datastore is identical to the one of previous major +releases: + +1. If you are planning on upgrading Kong while 0.12 nodes are running against + the same datastore, make sure those nodes are warm enough (they should have + most of your entities cached already) or temporarily disable your APIs. +2. Provision a 0.13 node and configure it as you wish (environment variables/ + configuration file). Make sure to point this new 0.13 node to your current + datastore. +3. **Without starting the 0.13 node**, run the 0.13 migrations against your + current datastore: + +``` +$ kong migrations up [-c kong.conf] +``` + +As usual, this step should be executed from a **single node**. + +4. You can now provision a fresh 0.13 cluster pointing to your migrated + datastore and start your 0.13 nodes. +5. Gradually switch your traffic from the 0.12 cluster to the new 0.13 cluster. + Remember, once your database is migrated, your 0.12 nodes will rely on + their cache and not on the underlying database. Your traffic should switch + to the new cluster as quickly as possible. +6. Once your traffic is fully migrated to the 0.13 cluster, decommission + your 0.12 cluster. + +You have now successfully upgraded your cluster to run 0.13 nodes exclusively. + +## Upgrade to `0.12.x` + +As it is the case most of the time, this new major version of Kong comes with +a few **database migrations**, some breaking changes, databases deprecation +notices, and minor updates to the NGINX configuration template. + +This document will only highlight the breaking changes that you need to be +aware of, and describe a recommended upgrade path. We recommend that you +consult the full [0.12.0 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a +complete list of changes and new features. + +See below the breaking changes section for a detailed list of steps recommended +to **run migrations** and upgrade from a previous version of Kong. + +#### Deprecation notices + +Starting with 0.12.0, we are announcing the deprecation of older versions +of our supported databases: + +- Support for PostgreSQL 9.4 is deprecated. Users are advised to upgrade to + 9.5+ +- Support for Cassandra 2.1 and below is deprecated. Users are advised to + upgrade to 2.2+ + +Note that the above-deprecated versions are still supported in this release, +but will be dropped in subsequent ones. + +#### Breaking changes + +##### Configuration + +- Several updates were made to the NGINX configuration template. If you are + using a custom template, you **must** apply those modifications. See below + for a list of changes to apply. + +##### Core + +- The required OpenResty version has been bumped to 1.11.2.5. If you + are installing Kong from one of our distribution packages, you are not + affected by this change. +- As Kong now executes subsequent plugins when a request is being + short-circuited (e.g. HTTP 401 responses from auth plugins), plugins that + run in the header or body filter phases will be run upon such responses + from the access phase. It is possible that some of these plugins (e.g. your + custom plugins) now run in scenarios where they were not previously expected + to run. + +##### Admin API + +- By default, the Admin API now only listens on the local interface. + We consider this change to be an improvement in the default security policy + of Kong. If you are already using Kong, and your Admin API still binds to all + interfaces, consider updating it as well. You can do so by updating the + `admin_listen` configuration value, like so: `admin_listen = 127.0.0.1:8001`. + + :red_circle: **Note to Docker users**: Beware of this change as you may have + to ensure that your Admin API is reachable via the host's interface. + You can use the `-e KONG_ADMIN_LISTEN` argument when provisioning your + container(s) to update this value; for example, + `-e KONG_ADMIN_LISTEN=0.0.0.0:8001`. + +- The `/upstreams/:upstream_name_or_id/targets/` has been updated to not show + the full list of Targets anymore, but only the ones that are currently + active in the load balancer. To retrieve the full history of Targets, you can + now query `/upstreams/:upstream_name_or_id/targets/all`. The + `/upstreams/:upstream_name_or_id/targets/active` endpoint has been removed. +- The `orderlist` property of Upstreams has been removed. + +##### CLI + +- The `$ kong compile` command which was deprecated in 0.11.0 has been removed. + +##### Plugins + +- In logging plugins, the `request.request_uri` field has been renamed to + `request.url`. + +--- + +If you use a custom NGINX configuration template from Kong 0.11, before +attempting to run any 0.12 node, make sure to apply the following change to +your template: + +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index 5ab65ca3..8a6abd64 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -32,6 +32,7 @@ lua_shared_dict kong 5m; + lua_shared_dict kong_cache ${{MEM_CACHE_SIZE}}; + lua_shared_dict kong_process_events 5m; + lua_shared_dict kong_cluster_events 5m; ++lua_shared_dict kong_healthchecks 5m; + > if database == "cassandra" then + lua_shared_dict kong_cassandra 5m; + > end +``` + +--- + +You can now start migrating your cluster from `0.11.x` to `0.12`. If you are +doing this upgrade "in-place", against the datastore of a running 0.11 cluster, +then for a short period of time, your database schema won't be fully compatible +with your 0.11 nodes anymore. This is why we suggest either performing this +upgrade when your 0.11 cluster is warm and most entities are cached, or against +a new database, if you can migrate your data. If you wish to temporarily make +your APIs unavailable, you can leverage the +[request-termination](https://getkong.org/plugins/request-termination/) plugin. + +The path to upgrade a 0.11 datastore is identical to the one of previous major +releases: + +1. If you are planning on upgrading Kong while 0.11 nodes are running against + the same datastore, make sure those nodes are warm enough (they should have + most of your entities cached already), or temporarily disable your APIs. +2. Provision a 0.12 node and configure it as you wish (environment variables/ + configuration file). Make sure to point this new 0.12 node to your current + datastore. +3. **Without starting the 0.12 node**, run the 0.12 migrations against your + current datastore: + +``` +$ kong migrations up [-c kong.conf] +``` + +As usual, this step should be executed from a **single node**. + +4. You can now provision a fresh 0.12 cluster pointing to your migrated + datastore and start your 0.12 nodes. +5. Gradually switch your traffic from the 0.11 cluster to the new 0.12 cluster. + Remember, once your database is migrated, your 0.11 nodes will rely on + their cache and not on the underlying database. Your traffic should switch + to the new cluster as quickly as possible. +6. Once your traffic is fully migrated to the 0.12 cluster, decommission + your 0.11 cluster. + +You have now successfully upgraded your cluster to run 0.12 nodes exclusively. + +## Upgrade to `0.11.x` + +Along with the usual database migrations shipped with our major releases, this +particular release introduces quite a few changes in behavior and, most +notably, the enforced manual migrations process and the removal of the Serf +dependency for cache invalidation between Kong nodes of the same cluster. + +This document will only highlight the breaking changes that you need to be +aware of, and describe a recommended upgrade path. We recommend that you +consult the full [0.11.0 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a +complete list of changes and new features. + +#### Breaking changes + +##### Configuration + +- Several updates were made to the Nginx configuration template. If you are + using a custom template, you **must** apply those modifications. See below + for a list of changes to apply. + +##### Migrations & Deployment + +- Migrations are **not** executed automatically by `kong start` anymore. + Migrations are now a **manual** process, which must be executed via the `kong + migrations` command. In practice, this means that you have to run `kong + migrations up [-c kong.conf]` in one of your nodes **before** starting your + Kong nodes. This command should be run from a **single** node/container to + avoid several nodes running migrations concurrently and potentially + corrupting your database. Once the migrations are up-to-date, it is + considered safe to start multiple Kong nodes concurrently. +- Serf is **not** a dependency anymore. Kong nodes now handle cache + invalidation events via a built-in database polling mechanism. See the new + "Datastore Cache" section of the configuration file which contains 3 new + documented properties: `db_update_frequency`, `db_update_propagation`, and + `db_cache_ttl`. If you are using Cassandra, you **should** pay a particular + attention to the `db_update_propagation` setting, as you **should not** use + the default value of `0`. + +**Note for Docker users:** Because of the aforementioned breaking change, if +you are running Kong with Docker, you will now need to run the migrations from +a single, ephemeral container. You can follow the [Docker installation +instructions](https://getkong.org/install/docker/) (see "2. Prepare your +database") for more details about this process. + +##### Core + +- Kong now requires OpenResty `1.11.2.4`. OpenResty's LuaJIT can now be built + with Lua 5.2 compatibility, and the `--without-luajit-lua52` flag can be + omitted. +- While Kong now correctly proxies downstream `X-Forwarded-*` headers, the + introduction of the new `trusted_ips` property also means that Kong will + only do so when the request comes from a trusted client IP. This is also + the condition under which the `X-Real-IP` header will be trusted by Kong + or not. + In order to enforce security best practices, we took the stance of **not** + trusting any client IP by default. If you wish to rely on such headers, you + will need to configure `trusted_ips` (see the Kong configuration file) to + your needs. +- The API Object property `http_if_terminated` is now set to `false` by + default. For Kong to evaluate the client `X-Forwarded-Proto` header, you must + now configure Kong to trust the client IP (see above change), **and** you + must explicitly set this value to `true`. This affects you if you are doing + SSL termination somewhere before your requests hit Kong, and if you have + configured `https_only` on the API, or if you use a plugin that requires + HTTPS traffic (e.g. OAuth2). +- The internal DNS resolver now honours the `search` and `ndots` configuration + options of your `resolv.conf` file. Make sure that DNS resolution is still + consistent in your environment, and consider eventually not using FQDNs + anymore. + +##### Admin API + +- Due to the removal of Serf, Kong is now entirely stateless. As such, the + `/cluster` endpoint has for now disappeared. This endpoint, in previous + versions of Kong, retrieved the state of the Serf agent running on other + nodes to ensure they were part of the same cluster. Starting from 0.11, all + Kong nodes connected to the same datastore are guaranteed to be part of the + same cluster without requiring additional channels of communication. +- The Admin API `/status` endpoint does not return a count of the database + entities anymore. Instead, it now returns a `database.reachable` boolean + value, which reflects the state of the connection between Kong and the + underlying database. Please note that this flag **does not** reflect the + health of the database itself. + +##### Plugins development + +- The upstream URI is now determined via the Nginx `$upstream_uri` variable. + Custom plugins using the `ngx.req.set_uri()` API will not be taken into + consideration anymore. One must now set the `ngx.var.upstream_uri` variable + from the Lua land. +- The `hooks.lua` module for custom plugins is dropped, along with the + `database_cache.lua` module. Database entities caching and eviction has been + greatly improved to simplify and automate most caching use-cases. See the + [plugins development + guide](https://getkong.org/docs/0.11.x/plugin-development/entities-cache/) + for more details about the new underlying mechanism, or see the below + section of this document on how to update your plugin's cache invalidation + mechanism for 0.11.0. +- To ensure that the order of execution of plugins is still the same for + vanilla Kong installations, we had to update the `PRIORITY` field of some of + our bundled plugins. If your custom plugin must run after or before a + specific bundled plugin, you might have to update your plugin's `PRIORITY` + field as well. The complete list of plugins and their priorities is available + on the [plugins development + guide](https://getkong.org/docs/0.11.x/plugin-development/custom-logic/). + +#### Deprecations + +##### CLI + +- The `kong compile` command has been deprecated. Instead, prefer using + the new `kong prepare` command. + +--- + +If you use a custom Nginx configuration template from Kong 0.10, before +attempting to run any 0.11 node, make sure to apply the following changes to +your template: + +```diff +diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua +index 3c038595..faa97ffe 100644 +--- a/kong/templates/nginx_kong.lua ++++ b/kong/templates/nginx_kong.lua +@@ -19,25 +19,23 @@ error_log ${{PROXY_ERROR_LOG}} ${{LOG_LEVEL}}; + >-- reset_timedout_connection on; # disabled until benchmarked + > end + +-client_max_body_size 0; ++client_max_body_size ${{CLIENT_MAX_BODY_SIZE}}; + proxy_ssl_server_name on; + underscores_in_headers on; + +-real_ip_header X-Forwarded-For; +-set_real_ip_from 0.0.0.0/0; +-real_ip_recursive on; +- + lua_package_path '${{LUA_PACKAGE_PATH}};;'; + lua_package_cpath '${{LUA_PACKAGE_CPATH}};;'; + lua_code_cache ${{LUA_CODE_CACHE}}; + lua_socket_pool_size ${{LUA_SOCKET_POOL_SIZE}}; + lua_max_running_timers 4096; + lua_max_pending_timers 16384; +-lua_shared_dict kong 4m; +-lua_shared_dict cache ${{MEM_CACHE_SIZE}}; +-lua_shared_dict cache_locks 100k; +-lua_shared_dict process_events 1m; +-lua_shared_dict cassandra 5m; ++lua_shared_dict kong 5m; ++lua_shared_dict kong_cache ${{MEM_CACHE_SIZE}}; ++lua_shared_dict kong_process_events 5m; ++lua_shared_dict kong_cluster_events 5m; ++> if database == "cassandra" then ++lua_shared_dict kong_cassandra 5m; ++> end + lua_socket_log_errors off; + > if lua_ssl_trusted_certificate then + lua_ssl_trusted_certificate '${{LUA_SSL_TRUSTED_CERTIFICATE}}'; +@@ -45,8 +43,6 @@ lua_ssl_verify_depth ${{LUA_SSL_VERIFY_DEPTH}}; + > end + + init_by_lua_block { +- require 'luarocks.loader' +- require 'resty.core' + kong = require 'kong' + kong.init() + } +@@ -65,28 +61,19 @@ upstream kong_upstream { + keepalive ${{UPSTREAM_KEEPALIVE}}; + } + +-map $http_upgrade $upstream_connection { +- default keep-alive; +- websocket upgrade; +-} +- +-map $http_upgrade $upstream_upgrade { +- default ''; +- websocket websocket; +-} +- + server { + server_name kong; +- listen ${{PROXY_LISTEN}}; +- error_page 404 408 411 412 413 414 417 /kong_error_handler; ++ listen ${{PROXY_LISTEN}}${{PROXY_PROTOCOL}}; ++ error_page 400 404 408 411 412 413 414 417 /kong_error_handler; + error_page 500 502 503 504 /kong_error_handler; + + access_log ${{PROXY_ACCESS_LOG}}; + error_log ${{PROXY_ERROR_LOG}} ${{LOG_LEVEL}}; + ++ client_body_buffer_size ${{CLIENT_BODY_BUFFER_SIZE}}; + + > if ssl then +- listen ${{PROXY_LISTEN_SSL}} ssl; ++ listen ${{PROXY_LISTEN_SSL}} ssl${{HTTP2}}${{PROXY_PROTOCOL}}; + ssl_certificate ${{SSL_CERT}}; + ssl_certificate_key ${{SSL_CERT_KEY}}; + ssl_protocols TLSv1.1 TLSv1.2; +@@ -105,9 +92,22 @@ server { + proxy_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}}; + > end + ++ real_ip_header ${{REAL_IP_HEADER}}; ++ real_ip_recursive ${{REAL_IP_RECURSIVE}}; ++> for i = 1, #trusted_ips do ++ set_real_ip_from $(trusted_ips[i]); ++> end ++ + location / { +- set $upstream_host nil; +- set $upstream_scheme nil; ++ set $upstream_host ''; ++ set $upstream_upgrade ''; ++ set $upstream_connection ''; ++ set $upstream_scheme ''; ++ set $upstream_uri ''; ++ set $upstream_x_forwarded_for ''; ++ set $upstream_x_forwarded_proto ''; ++ set $upstream_x_forwarded_host ''; ++ set $upstream_x_forwarded_port ''; + + rewrite_by_lua_block { + kong.rewrite() +@@ -118,17 +118,18 @@ server { + } + + proxy_http_version 1.1; +- proxy_set_header X-Real-IP $remote_addr; +- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +- proxy_set_header X-Forwarded-Proto $scheme; +- proxy_set_header Host $upstream_host; +- proxy_set_header Upgrade $upstream_upgrade; +- proxy_set_header Connection $upstream_connection; +- proxy_pass_header Server; +- +- proxy_ssl_name $upstream_host; +- +- proxy_pass $upstream_scheme://kong_upstream; ++ proxy_set_header Host $upstream_host; ++ proxy_set_header Upgrade $upstream_upgrade; ++ proxy_set_header Connection $upstream_connection; ++ proxy_set_header X-Forwarded-For $upstream_x_forwarded_for; ++ proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto; ++ proxy_set_header X-Forwarded-Host $upstream_x_forwarded_host; ++ proxy_set_header X-Forwarded-Port $upstream_x_forwarded_port; ++ proxy_set_header X-Real-IP $remote_addr; ++ proxy_pass_header Server; ++ proxy_pass_header Date; ++ proxy_ssl_name $upstream_host; ++ proxy_pass $upstream_scheme://kong_upstream$upstream_uri; + + header_filter_by_lua_block { + kong.header_filter() +@@ -146,7 +147,7 @@ server { + location = /kong_error_handler { + internal; + content_by_lua_block { +- require('kong.core.error_handlers')(ngx) ++ kong.handle_error() + } + } + } +@@ -162,7 +163,7 @@ server { + client_body_buffer_size 10m; + + > if admin_ssl then +- listen ${{ADMIN_LISTEN_SSL}} ssl; ++ listen ${{ADMIN_LISTEN_SSL}} ssl${{ADMIN_HTTP2}}; + ssl_certificate ${{ADMIN_SSL_CERT}}; + ssl_certificate_key ${{ADMIN_SSL_CERT_KEY}}; + ssl_protocols TLSv1.1 TLSv1.2; +@@ -176,15 +177,7 @@ server { + location / { + default_type application/json; + content_by_lua_block { +- ngx.header['Access-Control-Allow-Origin'] = '*' +- +- if ngx.req.get_method() == 'OPTIONS' then +- ngx.header['Access-Control-Allow-Methods'] = 'GET,HEAD,PUT,PATCH,POST,DELETE' +- ngx.header['Access-Control-Allow-Headers'] = 'Content-Type' +- ngx.exit(204) +- end +- +- require('lapis').serve('kong.api') ++ kong.serve_admin_api() + } + } +``` + +Once those changes have been applied, you will be able to benefit from the new +configuration properties and bug fixes that 0.11 introduces. + +--- + +If you are maintaining your own plugin, and if you are using the 0.10.x +`database_cache.lua` module to cache your datastore entities, you probably +included a `hooks.lua` module in your plugin as well. + +In 0.11, most of the clutter surrounding cache invalidation is now gone, and +handled automatically by Kong for most use-cases. + +- The `hooks.lua` module is now ignored by Kong. You can safely remove it from + your plugins. +- The `database_cache.lua` module is replaced with `singletons.cache`. You + should not require `database_cache` anymore in your plugin's code. + +To update your plugin's caching mechanism to 0.11, you must implement automatic +or manual invalidation. + +##### Automatic cache invalidation + +Let's assume your plugin had the following code that we wish to update for +0.11 compatibility: + +```lua +local credential, err = cache.get_or_set(cache.keyauth_credential_key(key), + nil, load_credential, key) +if err then + return responses.send_HTTP_INTERNAL_SERVER_ERROR(err) +end +``` + +Along with the following `hooks.lua` file: + +```lua +local events = require "kong.core.events" +local cache = require "kong.tools.database_cache" + +local function invalidate(message_t) + if message_t.collection == "keyauth_credentials" then + cache.delete(cache.keyauth_credential_key(message_t.old_entity and + message_t.old_entity.key or + message_t.entity.key)) + end +end + +return { + [events.TYPES.ENTITY_UPDATED] = function(message_t) + invalidate(message_t) + end, + [events.TYPES.ENTITY_DELETED] = function(message_t) + invalidate(message_t) + end +} +``` + +By adding the following `cache_key` property to your custom entity's schema: + +```lua +local SCHEMA = { + primary_key = { "id" }, + table = "keyauth_credentials", + cache_key = { "key" }, -- cache key for this entity + fields = { + id = { type = "id" }, + consumer_id = { type = "id", required = true, foreign = "consumers:id"}, + key = { type = "string", required = false, unique = true } + } +} + +return { keyauth_credentials = SCHEMA } +``` + +You can now generate a unique cache key for that entity and cache it like so +in your business logic and hot code paths: + +```lua +local singletons = require "kong.singletons" + +local apikey = request.get_uri_args().apikey +local cache_key = singletons.dao.keyauth_credentials:cache_key(apikey) + +local credential, err = singletons.cache:get(cache_key, nil, load_entity_key, + apikey) +if err then + return response.HTTP_INTERNAL_SERVER_ERROR(err) +end + +-- do something with the retrieved credential +``` + +Now, cache invalidation will be an automatic process: every CRUD operation that +affects this API key will make Kong auto-generate the affected `cache_key`, +and send broadcast it to all of the other nodes on the cluster so they can +evict that particular value from their cache, and fetch the fresh value from +the datastore on the next request. + +When a parent entity is receiving a CRUD operation (e.g. the Consumer owning +this API key, as per our schema's `consumer_id` attribute), Kong performs the +cache invalidation mechanism for both the parent and the child entity. + +Thanks to this new property, the `hooks.lua` module is not required anymore and +your plugins can perform datastore caching much more easily. + +##### Manual cache invalidation + +In some cases, the `cache_key` property of an entity's schema is not flexible +enough, and one must manually invalidate its cache. Reasons for this could be +that the plugin is not defining a relationship with another entity via the +traditional `foreign = "parent_entity:parent_attribute"` syntax, or because +it is not using the `cache_key` method from its DAO, or even because it is +somehow abusing the caching mechanism. + +In those cases, you can manually set up your own subscriber to the same +invalidation channels Kong is listening to, and perform your own, custom +invalidation work. This process is similar to the old `hooks.lua` module. + +To listen on invalidation channels inside of Kong, implement the following in +your plugin's `init_worker` handler: + +```lua +local singletons = require "kong.singletons" + +function MyCustomHandler:init_worker() + local worker_events = singletons.worker_events + + -- listen to all CRUD operations made on Consumers + worker_events.register(function(data) + + end, "crud", "consumers") + + -- or, listen to a specific CRUD operation only + worker_events.register(function(data) + print(data.operation) -- "update" + print(data.old_entity) -- old entity table (only for "update") + print(data.entity) -- new entity table + print(data.schema) -- entity's schema + end, "crud", "consumers:update") +end +``` + +Once the above listeners are in place for the desired entities, you can perform +manual invalidations of any entity that your plugin has cached as you wish so. +For instance: + +```lua +singletons.worker_events.register(function(data) + if data.operation == "delete" then + local cache_key = data.entity.id + singletons.cache:invalidate("prefix:" .. cache_key) + end +end, "crud", "consumers") +``` + +--- + +You can now start migrating your cluster from `0.10.x` to `0.11`. If you are +doing this upgrade "in-place", against the datastore of a running 0.10 cluster, +then for a short period of time, your database schema won't be fully compatible +with your 0.10 nodes anymore. This is why we suggest either performing this +upgrade when your 0.10 cluster is warm and most entities are cached, or against +a new database, if you can migrate your data. If you wish to temporarily make +your APIs unavailable, you can leverage the new +[request-termination](https://getkong.org/plugins/request-termination/) plugin. + +The path to upgrade a 0.10 datastore is identical to the one of previous major +releases: + +1. If you are planning on upgrading Kong while 0.10 nodes are running against + the same datastore, make sure those nodes are warm enough (they should have + most of your entities cached already), or temporarily disable your APIs. +2. Provision a 0.11 node and configure it as you wish (environment variables/ + configuration file). Make sure to point this new 0.11 node to your current + datastore. +3. **Without starting the 0.11 node**, run the 0.11 migrations against your + current datastore: + +``` +$ kong migrations up [-c kong.conf] +``` + +As usual, this step should be executed from a **single node**. + +4. You can now provision a fresh 0.11 cluster pointing to your migrated + datastore and start your 0.11 nodes. +5. Gradually switch your traffic from the 0.10 cluster to the new 0.11 cluster. + Remember, once your database is migrated, your 0.10 nodes will rely on + their cache and not on the underlying database. Your traffic should switch + to the new cluster as quickly as possible. +6. Once your traffic is fully migrated to the 0.11 cluster, decommission + your 0.10 cluster. + +Once all of your 0.10 nodes are fully decommissioned, you can consider removing +the Serf executable from your environment as well, since Kong 0.11 does not +depend on it anymore. + +## Upgrade to `0.10.x` + +Due to the breaking changes introduced in this version, we recommend that you +carefully test your cluster deployment. + +Kong 0.10 introduced the following breaking changes: + +- API Objects (as configured via the Admin API) do **not** support the + `request_host` and `request_uri` fields anymore. The 0.10 migrations should + upgrade your current API Objects, but make sure to read the new [0.10 Proxy + Guide](https://getkong.org/docs/0.10.x/proxy) to learn the new routing + capabilities of Kong. This means that Kong can now route incoming requests + according to a combination of Host headers, URIs, and HTTP + methods. +- The `upstream_url` field of API Objects does not accept trailing slashes anymore. +- Dynamic SSL certificates serving is now handled by the core and **not** + through the `ssl` plugin anymore. This version introduced the `/certificates` + and `/snis` endpoints. See the new [0.10 Proxy + Guide](https://getkong.org/docs/0.10.x/proxy) to learn more about how to + configure your SSL certificates on your APIs. The `ssl` plugin has been + removed. +- The preferred version of OpenResty is now `1.11.2.2`. However, this version + requires that you compiled OpenResty with the `--without-luajit-lua52` flag. + Make sure to do so if you install OpenResty and Kong from source. +- Dnsmasq is not a dependency anymore (However, be careful before removing it + if you configured it to be your DNS name server via Kong's [`resolver` + property](https://getkong.org/docs/0.9.x/configuration/#dns-resolver-section)) +- The `cassandra_contact_points` property does not allow specifying a port + anymore. All Cassandra nodes must listen on the same port, which can be + tweaked via the `cassandra_port` property. +- If you are upgrading to `0.10.1` or `0.10.2` and using the CORS plugin, pay + extra attention to a regression that was introduced in `0.10.1`: + Previously, the plugin would send the `*` wildcard when `config.origin` was + not specified. With this change, the plugin **does not** send the `*` + wildcard by default anymore. You will need to specify it manually when + configuring the plugin, with `config.origins=*`. This behavior is to be fixed + in a future release. + +We recommend that you consult the full [0.10.0 +Changelog](https://github.com/Kong/kong/blob/master/CHANGELOG.md) for a full +list of changes and new features, including load balancing capabilities, +support for Cassandra 3.x, SRV records resolution, and much more. + +Here is how to ensure a smooth upgrade from a Kong `0.9.x` cluster to `0.10`: + +1. Make sure your 0.9 cluster is warm because your + datastore will be incompatible with your 0.9 Kong nodes once migrated. + Most of your entities should be cached + by the running Kong nodes already (APIs, Consumers, Plugins). +2. Provision a 0.10 node and configure it as you wish (environment variables/ + configuration file). Make sure to point this new 0.10 node to your current + datastore. +3. **Without starting the 0.10 node**, run the 0.10 migrations against your + current datastore: + +``` +$ kong migrations up <-c kong.conf> +``` + +As usual, this step should be executed from a single node. + +4. You can now provision a fresh 0.10 cluster pointing to your migrated + datastore and start your 0.10 nodes. +5. Gradually switch your traffic from the 0.9 cluster to the new 0.10 cluster. + Remember, once your database is migrated, your 0.9 nodes will rely on + their cache and not on the underlying database. Your traffic should switch + to the new cluster as quickly as possible. +6. Once your traffic is fully migrated to the 0.10 cluster, decommission + your 0.9 cluster. + +## Upgrade to `0.9.x` + +PostgreSQL is the new default datastore for Kong. If you were using Cassandra +and you are upgrading, you must explicitly set `cassandra` as your `database`. + +This release introduces a new CLI, which uses the +[lua-resty-cli](https://github.com/openresty/resty-cli) interpreter. As such, +the `resty` executable (shipped in the OpenResty bundle) must be available in +your `$PATH`. Additionally, the `bin/kong` executable is not installed through +Luarocks anymore, and must be placed in your `$PATH` as well. This change of +behavior is taken care of if you are using one of the official Kong packages. + +Once Kong updated, familiarize yourself with its new configuration format, and +consider setting some of its properties via environment variables if the need +arises. This behavior, as well as all available settings, are documented in the +`kong.conf.default` file shipped with this version. + +Once your nodes configured, we recommend that you seemingly redirect your +traffic through the new Kong 0.9 nodes before decommissioning your old nodes. + +## Upgrade to `0.8.x` + +No important breaking changes for this release, just be careful to not use the +long deprecated routes `/consumers/:consumer/keyauth/` and +`/consumers/:consumer/basicauth/` as instructed in the Changelog. As always, +also make sure to check the configuration file for new properties (this release +allows you to configure the read/write consistency of Cassandra). + +Let's talk about **PostgreSQL**. To use it instead of Cassandra, follow those +steps: + +* Get your hands on a 9.4+ server (being compatible with Postgres 9.4 allows + you to use [Amazon RDS](https://aws.amazon.com/rds/)) +* Create a database, (maybe a user too?), let's say `kong` +* Update your Kong configuration: + +```yaml +# as always, be careful about your YAML formatting +database: postgres +postgres: + host: "127.0.0.1" + port: 5432 + user: kong + password: kong + database: kong +``` + +As usual, migrations should run from kong start, but as a reminder and just in +case, here are some tips: + +Reset the database with (careful, you'll lose all data): +``` +$ kong migrations reset --config kong.yml +``` + +Run the migrations manually with: +``` +$ kong migrations up --config kong.yml +``` + +If needed, list your migrations for debug purposes with: +``` +$ kong migrations list --config kong.yml +``` + +**Note**: This release does not provide a mean to migrate from Cassandra to +PostgreSQL. Additionally, we recommend that you **do not** use `kong reload` if +you switch your cluster from Cassandra to PostgreSQL. Instead, we recommend +that you migrate by spawning a new cluster and gradually redirect your traffic +before decommissioning your old nodes. + +## Upgrade to `0.7.x` + +If you are running a source installation, you will need to upgrade OpenResty to +its `1.9.7.*` version. The good news is that this family of releases does not +need to patch the NGINX core anymore to enable SSL support. If you install Kong +from one of the distribution packages, they already include the appropriate +OpenResty, simply download and install the appropriate package for your +platform. + +As described in the Changelog, this upgrade has benefits, such as the SSL +support and fixes for critical NGINX vulnerabilities, but also requires that +you upgrade the `nginx` property of your Kong config because it is not +backwards compatible. + +- We advise that you retrieve the `nginx` property from the `0.7.x` + configuration file, and use it in yours with the changes you feel are + appropriate. + +- Finally, you can reload Kong as usual: + +```shell +$ kong reload [-c configuration_file] +``` + +**Note**: We expose the underlying NGINX configuration as a way for Kong to be +as flexible as possible and allow you to bend your NGINX instance to your +needs. We are aware that many of you do not need to customize it and such +changes should not affect you. Plans are to embed the NGINX configuration in +Kong, while still allowing customization for the most demanding users. +[#217](https://github.com/Kong/kong/pull/217) is the place to discuss this +and share thoughts/needs. + +## Upgrade to `0.6.x` + +**Note**: if you are using Kong 0.4.x or earlier, you must first upgrade to +Kong 0.5.x. + +The configuration file changed in this release. Make sure to check out the new +default one and update it to your needs. In particular, make sure that: + +```yaml +plugins_available: + - key-auth + - ... + - custom-plugin +proxy_port: ... +proxy_ssl_port: ... +admin_api_port: ... +databases_available: + cassandra: + properties: + contact_points: + - ... +``` + +becomes: + +```yaml +custom_plugins: + - only-custom-plugins +proxy_listen: ... +proxy_listen_ssl: ... +admin_api_listen: ... +cassandra: + contact_points: + - ... +``` + +Secondly, if you installed Kong from source or maintain a development +installation, you will need to have [Serf](https://www.serfdom.io) installed on +your system and available in your `$PATH`. Serf is included with all the +distribution packages and images available at +[getkong.org/install](https://getkong.org/install/). + +The same way, this should already be the case but make sure that LuaJIT is in +your `$PATH` too as the CLI interpreter switched from Lua 5.1 to LuaJIT. +Distribution packages also include LuaJIT. + +In order to start Kong with its new clustering and cache invalidation +capabilities, you will need to restart your node(s) (and not reload): + +```shell +$ kong restart [-c configuration_file] +``` + +Read more about the new clustering capabilities of Kong 0.6.0 and its +configurations in the [Clustering +documentation](https://getkong.org/docs/0.6.x/clustering/). + +## Upgrade to `0.5.x` + +Migrating to 0.5.x can be done **without downtime** by following those +instructions. It is important that you be running Kong `0.4.2` and have the +latest release of Python 2.7 on your system when executing those steps. + +> Several changes were introduced in this version: some plugins and properties +> were renamed and the database schema slightly changed to introduce "plugins +> migrations". Now, each plugin can have its own migration if it needs to store +> data in your cluster. This is not a regular migration since the schema of the +> table handling the migrations itself changed. + +##### 1. Configuration file + +You will need to update your configuration file. Replace the +`plugins_available` values with: + +```yaml +plugins_available: + - ssl + - jwt + - acl + - cors + - oauth2 + - tcp-log + - udp-log + - file-log + - http-log + - key-auth + - hmac-auth + - basic-auth + - ip-restriction + - mashape-analytics + - request-transformer + - response-transformer + - request-size-limiting + - rate-limiting + - response-ratelimiting +``` + +You can still remove plugins you don't use for a lighter Kong. + +Also replace the Cassandra `hosts` property with `contact_points`: + +```yaml +properties: + contact_points: + - "..." + - "..." + timeout: 1000 + keyspace: kong + keepalive: 60000 +``` + +##### 2. Migration script + +[This Python +script](https://github.com/Kong/kong/blob/0.5.0/scripts/migration.py) will +take care of migrating your database schema should you execute the following +instructions: + +```shell +# First, make sure you are already running Kong 0.4.2 + +# Clone the Kong git repository if you don't already have it: +$ git clone https://github.com/Kong/kong.git + +# Go to the 'scripts/' folder: +$ cd kong/scripts + +# Install the Python script dependencies: +$ pip install cassandra-driver==2.7.2 pyyaml + +# The script will use the first Cassandra contact point in your Kong configuration file +# (the first of the 'contact_points' property) so make sure it is valid and has the format 'host:port'. + +# Run the migration script: +$ python migration.py -c /path/to/kong/config +``` + +If everything went well the script should print a success message. **At this +point, your database is compatible with both Kong 0.4.2 and 0.5.x.** If you are +running more than one Kong node, you simply have to follow step 3. for each one +of them now. + +##### 3. Upgrade without downtime + +You can now upgrade Kong to `0.5.x.` Proceed as a regular upgrade and follow +the suggested upgrade path, in particular, the `kong reload` command. + +##### 4. Purge your Cassandra cluster + +Finally, once Kong has restarted in 0.5.x, run the migration script again, with +the `--purge` flag: + +```shell +$ python migration.py -c /path/to/kong/config --purge +``` + +Your cluster is now fully migrated to `0.5.x`. + +##### Other changes to acknowledge + +Some entities and properties were renamed to avoid confusion: + +- Properties belonging to APIs entities have been renamed for clarity: + - `public_dns` -> `request_host` + - `path` -> `request_path` + - `strip_path` -> `strip_request_path` + - `target_url` -> `upstream_url` +- `plugins_configurations` have been renamed to `plugins`, and their `value` + property has been renamed to `config` to avoid confusions. +- The Key authentication and Basic authentication plugins routes have changed: + +``` +Old route New route +/consumers/:consumer/keyauth -> /consumers/:consumer/key-auth +/consumers/:consumer/keyauth/:id -> /consumers/:consumer/key-auth/:id +/consumers/:consumer/basicauth -> /consumers/:consumer/basic-auth +/consumers/:consumer/basicauth/:id -> /consumers/:consumer/basic-auth/:id +``` + +The old routes are still maintained but will be removed in upcoming versions. +Consider them **deprecated**. + +- Admin API: + - The route to retrieve enabled plugins is now under `/plugins/enabled`. + - The route to retrieve a plugin's configuration schema is now under + `/plugins/schema/{plugin name}`. + +## Upgrade to Kong `0.4.2` + +The configuration format for specifying the port of your Cassandra instance +changed. Replace: + +```yaml +cassandra: + properties: + hosts: "localhost" + port: 9042 +``` + +by: + +```yaml +cassandra: + properties: + hosts: + - "localhost:9042" +``` + +## Upgrade to `0.3.x` + +Kong now requires a patch on OpenResty for SSL support. On Homebrew you will +need to reinstall OpenResty. + +#### Homebrew + +```shell +$ brew update +$ brew reinstall mashape/kong/ngx_openresty +$ brew upgrade kong +``` + +#### Troubleshoot + +If you are seeing a similar error on `kong start`: + +``` +nginx: [error] [lua] init_by_lua:5: Startup error: Cassandra error: Failed to +prepare statement: "SELECT id FROM apis WHERE path = ?;". Cassandra returned +error (Invalid): "Undefined name path in where clause ('path = ?')" +``` + +You can run the following command to update your schema: + +``` +$ kong migrations up +``` + +Please consider updating to `0.3.1` or greater which automatically handles the +schema migration. diff --git a/app/_assets/images/KogoBlue.svg b/app/_assets/images/KogoBlue.svg new file mode 100644 index 000000000000..eea4957ccb78 --- /dev/null +++ b/app/_assets/images/KogoBlue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/_assets/images/docs/dev-portal/azure-app-details.png b/app/_assets/images/docs/dev-portal/azure-app-details.png new file mode 100644 index 000000000000..51bc9c7a35a1 Binary files /dev/null and b/app/_assets/images/docs/dev-portal/azure-app-details.png differ diff --git a/app/_assets/images/docs/dev-portal/azure-app-reg.png b/app/_assets/images/docs/dev-portal/azure-app-reg.png new file mode 100644 index 000000000000..1171ea5d1ca1 Binary files /dev/null and b/app/_assets/images/docs/dev-portal/azure-app-reg.png differ diff --git a/app/_assets/images/docs/dev-portal/azure-app.png b/app/_assets/images/docs/dev-portal/azure-app.png new file mode 100644 index 000000000000..863f8e2f7672 Binary files /dev/null and b/app/_assets/images/docs/dev-portal/azure-app.png differ diff --git a/app/_assets/images/docs/dev-portal/azure-manifest.png b/app/_assets/images/docs/dev-portal/azure-manifest.png new file mode 100644 index 000000000000..8645408e6aea Binary files /dev/null and b/app/_assets/images/docs/dev-portal/azure-manifest.png differ diff --git a/app/_assets/images/docs/dev-portal/jwt-converter.png b/app/_assets/images/docs/dev-portal/jwt-converter.png new file mode 100644 index 000000000000..c232d7a0587e Binary files /dev/null and b/app/_assets/images/docs/dev-portal/jwt-converter.png differ diff --git a/app/_assets/images/docs/dev-portal/ms-azure-app-reg.png b/app/_assets/images/docs/dev-portal/ms-azure-app-reg.png new file mode 100644 index 000000000000..ea386cfc0277 Binary files /dev/null and b/app/_assets/images/docs/dev-portal/ms-azure-app-reg.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_degraphql.png b/app/_assets/images/icons/hub/kong-inc_degraphql.png index a6b8840c2e9d..e211f29d96d2 100644 Binary files a/app/_assets/images/icons/hub/kong-inc_degraphql.png and b/app/_assets/images/icons/hub/kong-inc_degraphql.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_exit-transformer.png b/app/_assets/images/icons/hub/kong-inc_exit-transformer.png index 255bcbed045a..ec05a7365fea 100644 Binary files a/app/_assets/images/icons/hub/kong-inc_exit-transformer.png and b/app/_assets/images/icons/hub/kong-inc_exit-transformer.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_graphql-rate-limiting-advanced.png b/app/_assets/images/icons/hub/kong-inc_graphql-rate-limiting-advanced.png index a6b8840c2e9d..84d34341c709 100644 Binary files a/app/_assets/images/icons/hub/kong-inc_graphql-rate-limiting-advanced.png and b/app/_assets/images/icons/hub/kong-inc_graphql-rate-limiting-advanced.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_kafka-log.png b/app/_assets/images/icons/hub/kong-inc_kafka-log.png index e69b9be859f6..a02f0175d81b 100644 Binary files a/app/_assets/images/icons/hub/kong-inc_kafka-log.png and b/app/_assets/images/icons/hub/kong-inc_kafka-log.png differ diff --git a/app/_assets/images/icons/hub/kong-inc_route-transformer-advanced.png b/app/_assets/images/icons/hub/kong-inc_route-transformer-advanced.png index 255bcbed045a..2e43b354bff6 100644 Binary files a/app/_assets/images/icons/hub/kong-inc_route-transformer-advanced.png and b/app/_assets/images/icons/hub/kong-inc_route-transformer-advanced.png differ diff --git a/app/_assets/images/icons/hub/yesinteractive_kongmap.png b/app/_assets/images/icons/hub/yesinteractive_kongmap.png new file mode 100644 index 000000000000..c0900467d5bc Binary files /dev/null and b/app/_assets/images/icons/hub/yesinteractive_kongmap.png differ diff --git a/app/_assets/javascripts/app.js b/app/_assets/javascripts/app.js index 02594fd4652b..a116551b21ff 100644 --- a/app/_assets/javascripts/app.js +++ b/app/_assets/javascripts/app.js @@ -1,232 +1,255 @@ /* globals $, history, analytics */ -'use strict' +"use strict"; $(function () { - var NAV_HEIGHT = 56 + var NAV_HEIGHT = 56; - var $window = $(window) - var $docs = $('#documentation') + var $window = $(window); + var $docs = $("#documentation"); - $('.navbar-toggle').on('click', function () { - var $navbar = $($(this).data('target')) - $navbar.slideToggle(150) - }) + $(".navbar-toggle").on("click", function () { + var $navbar = $($(this).data("target")); + $navbar.slideToggle(150); + }); - $('.scroll-to').on('click', function (e) { - e.preventDefault() + $(".scroll-to").on("click", function (e) { + e.preventDefault(); if ($(window).width() <= 1000) { - var offset = NAV_HEIGHT + 40 + var offset = NAV_HEIGHT + 40; } else { - var offset = NAV_HEIGHT + var offset = NAV_HEIGHT; } - $('html, body').animate({ - scrollTop: $($(this).attr('href')).offset().top - offset // Header height - }, 700) - }) + $("html, body").animate( + { + scrollTop: $($(this).attr("href")).offset().top - offset, // Header height + }, + 700 + ); + }); // Change header download button color - if (!$('body#enterprise').length) { - var introSectionHeight = $('.section.intro-section').outerHeight() || 38 - var $downloadBtn = $('.navbar-nav').find('.button') + if (!$("body#enterprise").length) { + var introSectionHeight = $(".section.intro-section").outerHeight() || 38; + var $downloadBtn = $(".navbar-nav").find(".button"); - $window.on('scroll', function () { - var scrollTop = $(this).scrollTop() + $window.on("scroll", function () { + var scrollTop = $(this).scrollTop(); if (scrollTop > introSectionHeight) { - $downloadBtn.removeClass('button-dark').addClass('button-primary') + $downloadBtn.removeClass("button-dark").addClass("button-primary"); } else { - $downloadBtn.removeClass('button-primary').addClass('button-dark') + $downloadBtn.removeClass("button-primary").addClass("button-dark"); } - }) + }); } // Hide banner on "I accept" and set cookie - $('.cookie-policy-accept').on('click', function (e) { - e.preventDefault() + $(".cookie-policy-accept").on("click", function (e) { + e.preventDefault(); - $('.cookie-policy-container').removeClass('showing') - $('.page').removeClass('page-cookie-policy') - setCookie('cookie-policy', 'agreed') - }) + $(".cookie-policy-container").removeClass("showing"); + $(".page").removeClass("page-cookie-policy"); + setCookie("cookie-policy", "agreed"); + }); - function getCookie (cname) { - var name = cname + '=' - var ca = document.cookie.split(';') + function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(";"); for (var i = 0; i < ca.length; i++) { - var c = ca[i] - while (c.charAt(0) === ' ') { - c = c.substring(1) + var c = ca[i]; + while (c.charAt(0) === " ") { + c = c.substring(1); } if (c.indexOf(name) === 0) { - return c.substring(name.length, c.length) + return c.substring(name.length, c.length); } } - return '' + return ""; } - function setCookie (cname, cvalue) { - var CookieDate = new Date() - CookieDate.setFullYear(CookieDate.getFullYear() + 1) - document.cookie = cname + '=' + cvalue + '; expires=' + CookieDate.toGMTString() + ';path=/' + function setCookie(cname, cvalue) { + var CookieDate = new Date(); + CookieDate.setFullYear(CookieDate.getFullYear() + 1); + document.cookie = + cname + + "=" + + cvalue + + "; expires=" + + CookieDate.toGMTString() + + ";path=/"; } - var isCookieSet = getCookie('cookie-policy') - if (isCookieSet === '') { - $('.cookie-policy-container').addClass('showing') - $('.page').addClass('page-cookie-policy') + var isCookieSet = getCookie("cookie-policy"); + if (isCookieSet === "") { + $(".cookie-policy-container").addClass("showing"); + $(".page").addClass("page-cookie-policy"); } // Page section on contribute page - $('.toggle-page-section').on('click', function (e) { - e.preventDefault() - var $link = $(this) + $(".toggle-page-section").on("click", function (e) { + e.preventDefault(); + var $link = $(this); - $link.parent().next('.page-section').stop().slideToggle(300, function () { - $link.toggleClass('active') - }) - }) + $link + .parent() + .next(".page-section") + .stop() + .slideToggle(300, function () { + $link.toggleClass("active"); + }); + }); // Tabs on download page - var $tabs = $('.tab-list li') - var $tabPanes = $('.tab-pane') + var $tabs = $(".tab-list li"); + var $tabPanes = $(".tab-pane"); - $tabs.on('click', function (e, disableTracking) { - e.preventDefault() + $tabs.on("click", function (e, disableTracking) { + e.preventDefault(); - var tabId = $(this).find('a').attr('href') + var tabId = $(this).find("a").attr("href"); - $tabs.removeClass('active').filter(this).addClass('active') - $tabPanes.removeClass('active').filter(tabId).addClass('active') + $tabs.removeClass("active").filter(this).addClass("active"); + $tabPanes.removeClass("active").filter(tabId).addClass("active"); if (history.pushState) { - history.pushState(null, null, tabId) + history.pushState(null, null, tabId); } else { - window.location.hash = tabId + window.location.hash = tabId; } if (!disableTracking) { - analytics.track('Choose installation method', { - installationMethod: tabId.substr(1) - }) + analytics.track("Choose installation method", { + installationMethod: tabId.substr(1), + }); } - }) + }); if (window.location.hash) { - $tabs.find('a[href="' + window.location.hash + '"]').trigger('click', true) + $tabs.find('a[href="' + window.location.hash + '"]').trigger("click", true); } // Subscribe form - $('#subscription_form, #follow_up_subscription_form').on('submit', function (e) { - e.preventDefault() + $("#subscription_form, #follow_up_subscription_form").on("submit", function ( + e + ) { + e.preventDefault(); - var form = $(this) - var email = form.find('[name="email"]').val() - var time = new Date().toString() + var form = $(this); + var email = form.find('[name="email"]').val(); + var time = new Date().toString(); var traits = { email: email, - environment: 'kong', + environment: "kong", newsletter_updates: true, - created_at: time - } + created_at: time, + }; - form.find('.message').html('') - form.find('[name="email"]').removeClass('error') + form.find(".message").html(""); + form.find('[name="email"]').removeClass("error"); if (!email || !isEmail(email)) { - $(this).find('.error-message').html('The e-mail address entered is invalid.') - form.find('[name="email"]').addClass('error') - return false + $(this) + .find(".error-message") + .html("The e-mail address entered is invalid."); + form.find('[name="email"]').addClass("error"); + return false; } - form.addClass('loading') + form.addClass("loading"); $.ajax({ - url: form.attr('action'), - type: 'POST', + url: form.attr("action"), + type: "POST", async: false, data: form.serialize(), xhrFields: { - withCredentials: true + withCredentials: true, }, success: function () { - console.log('Success') - } - }) + console.log("Success"); + }, + }); var track = function () { - analytics.track('request_newsletter_updates', { + analytics.track("request_newsletter_updates", { email: email, - request_date: time - }) - } + request_date: time, + }); + }; - analytics.identify(email, traits, track) + analytics.identify(email, traits, track); - form.find('[name="email"]').val() - $(this).find('.success-message').text('Thank you for signing up!') - return false - }) + form.find('[name="email"]').val(); + $(this).find(".success-message").text("Thank you for signing up!"); + return false; + }); // set utm_ values from query parameter - var getUrlParameter = function getUrlParameter (sParam) { - var sPageURL = decodeURIComponent(window.location.search.substring(1)) - var sURLVariables = sPageURL.split('&') - var sParameterName - var i - var x - var status = false - var urlParams = ['utm_source', 'utm_campaign', 'utm_medium', 'utm_content', 'utm_term'] - var paramValues = [] + var getUrlParameter = function getUrlParameter(sParam) { + var sPageURL = decodeURIComponent(window.location.search.substring(1)); + var sURLVariables = sPageURL.split("&"); + var sParameterName; + var i; + var x; + var status = false; + var urlParams = [ + "utm_source", + "utm_campaign", + "utm_medium", + "utm_content", + "utm_term", + ]; + var paramValues = []; for (i = 0; i < sURLVariables.length; i++) { - sParameterName = sURLVariables[i].split('=') + sParameterName = sURLVariables[i].split("="); if ($.inArray(sParameterName[0], urlParams) >= 0) { - setCookie(sParameterName[0], sParameterName[1], 30) - paramValues.push(sParameterName[0]) - status = true + setCookie(sParameterName[0], sParameterName[1], 30); + paramValues.push(sParameterName[0]); + status = true; } } if (status === true) { for (i = 0; i < urlParams.length; i++) { if ($.inArray(urlParams[i], paramValues) < 0) { - setCookie(urlParams[i], ' ', 30) + setCookie(urlParams[i], " ", 30); } } } for (x = 0; x < urlParams.length; x++) { if (getCookie(urlParams[x])) { - $('input[name="' + urlParams[x] + '"]').val(getCookie(urlParams[x])) + $('input[name="' + urlParams[x] + '"]').val(getCookie(urlParams[x])); } } - } + }; - getUrlParameter() + getUrlParameter(); // Check for email validation - function isEmail (email) { - var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/ - return regex.test(email) + function isEmail(email) { + var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; + return regex.test(email); } // Enterprise page demo request form - $('.demo-request-form').on('submit', function (e) { - e.preventDefault() + $(".demo-request-form").on("submit", function (e) { + e.preventDefault(); - var form = $(this) - var data = form.serializeArray() - var submitTime = new Date().toString() - var payload = {} - var fieldValues = {} + var form = $(this); + var data = form.serializeArray(); + var submitTime = new Date().toString(); + var payload = {}; + var fieldValues = {}; var relateiqFieldIds = { title: 8, tell_us_more: 6, @@ -235,321 +258,351 @@ $(function () { deployment: 14, company: 10, name: 13, - environment: 16 - } + environment: 16, + }; - form.addClass('loading') + form.addClass("loading"); for (var i = 0; i < data.length; i++) { - payload[data[i].name] = data[i].value + payload[data[i].name] = data[i].value; } - payload.environment = 'kong' + payload.environment = "kong"; - var traits = $.extend({ - enterprise: true, - created_at: submitTime - }, payload) + var traits = $.extend( + { + enterprise: true, + created_at: submitTime, + }, + payload + ); analytics.identify(payload.email, traits, function () { - analytics.track('request_enterprise_demo', $.extend({ - request_date: submitTime - }, payload)) - }) + analytics.track( + "request_enterprise_demo", + $.extend( + { + request_date: submitTime, + }, + payload + ) + ); + }); for (var field in payload) { if (payload[field]) { - fieldValues[relateiqFieldIds[field]] = [{ - raw: payload[field] - }] + fieldValues[relateiqFieldIds[field]] = [ + { + raw: payload[field], + }, + ]; } } $.ajax({ - url: 'https://mashaper-relateiq-v1.p.mashape.com/accounts', - method: 'POST', + url: "https://mashaper-relateiq-v1.p.mashape.com/accounts", + method: "POST", headers: { - 'authorization': 'Basic NTU2ZDcxYzdlNGIwMmM5ZTM3YjgxNzc1Ok9NbFNBVGM1QkFTOG1JbEtXZENMZFZ2Z3RqYQ==', - 'x-mashape-key': 'mJUINHSWBYmshREqNlfTBKtbBHDZp1N7VKhjsnUIUo4f4r3pVj' + authorization: + "Basic NTU2ZDcxYzdlNGIwMmM5ZTM3YjgxNzc1Ok9NbFNBVGM1QkFTOG1JbEtXZENMZFZ2Z3RqYQ==", + "x-mashape-key": "mJUINHSWBYmshREqNlfTBKtbBHDZp1N7VKhjsnUIUo4f4r3pVj", }, data: JSON.stringify({ name: payload.email, - fieldValues: fieldValues - }) + fieldValues: fieldValues, + }), }).always(function () { - form.addClass('complete') - }) - }) + form.addClass("complete"); + }); + }); // Docs page navigation if ($docs.length) { - var $nav = $docs.find('.page-navigation') - var $navItems = $nav.find('a') - var hash = window.location.hash + var $nav = $docs.find(".page-navigation"); + var $navItems = $nav.find("a"); + var hash = window.location.hash; var setNavItemActive = function () { - $navItems.removeClass('active').filter(this).addClass('active') - } + $navItems.removeClass("active").filter(this).addClass("active"); + }; if (hash) { $navItems.each(function () { - if ($(this).attr('href').indexOf(hash) !== -1) { - setNavItemActive.call(this) + if ($(this).attr("href").indexOf(hash) !== -1) { + setNavItemActive.call(this); } - }) + }); } - $navItems.on('click', setNavItemActive) - - $('.sidebar-toggle').click(function () { - $('.page-navigation').addClass('sidebar-open') - $('.docs-sidebar').addClass('sidebar-open') - }) - $('.page-navigation > .close-sidebar').click(function () { - $('.page-navigation').removeClass('sidebar-open') - }) - $('.docs-sidebar > .close-sidebar').click(function () { - $('.docs-sidebar').removeClass('sidebar-open') - }) - - $('.toc-sidebar-toggle').click(function () { - $('.docs-toc').addClass('sidebar-open') - }) - $('.docs-toc > .close-sidebar').click(function () { - $('.docs-toc').removeClass('sidebar-open') - }) - - $('.docs-toc > .collapse-toc').click(function () { - $('.docs-toc').addClass('collapsed') - $('.page-content-container').addClass('toc-collapsed') - setCookie('toc-collapsed', 'true') - }) - $('.docs-toc > .expand-toc').click(function () { - $('.docs-toc').removeClass('collapsed') - $('.page-content-container').removeClass('toc-collapsed') - setCookie('toc-collapsed', 'false') - }) - if (getCookie('toc-collapsed') === 'true') { - $('.docs-toc').addClass('collapsed') - $('.page-content-container').addClass('toc-collapsed') + $navItems.on("click", setNavItemActive); + + $(".sidebar-toggle").click(function () { + $(".page-navigation").addClass("sidebar-open"); + $(".docs-sidebar").addClass("sidebar-open"); + }); + $(".page-navigation > .close-sidebar").click(function () { + $(".page-navigation").removeClass("sidebar-open"); + }); + $(".docs-sidebar > .close-sidebar").click(function () { + $(".docs-sidebar").removeClass("sidebar-open"); + }); + + $(".toc-sidebar-toggle").click(function () { + $(".docs-toc").addClass("sidebar-open"); + }); + $(".docs-toc > .close-sidebar").click(function () { + $(".docs-toc").removeClass("sidebar-open"); + }); + + $(".docs-toc > .collapse-toc").click(function () { + $(".docs-toc").addClass("collapsed"); + $(".page-content-container").addClass("toc-collapsed"); + setCookie("toc-collapsed", "true"); + }); + $(".docs-toc > .expand-toc").click(function () { + $(".docs-toc").removeClass("collapsed"); + $(".page-content-container").removeClass("toc-collapsed"); + setCookie("toc-collapsed", "false"); + }); + if (getCookie("toc-collapsed") === "true") { + $(".docs-toc").addClass("collapsed"); + $(".page-content-container").addClass("toc-collapsed"); } - $('#search-version-icon').click(function () { - const searchVersion = $('.search-version-row') - if (searchVersion.hasClass('visible')) { - searchVersion.removeClass('visible') + $("#search-version-icon").click(function () { + const searchVersion = $(".search-version-row"); + if (searchVersion.hasClass("visible")) { + searchVersion.removeClass("visible"); } else { - searchVersion.addClass('visible') + searchVersion.addClass("visible"); } - }) + }); } // Analytics $('[href^="/install"]').each(function () { - var $link = $(this) + var $link = $(this); - analytics.trackLink(this, 'Clicked download', { - section: $link.closest('.navbar').length ? 'header' : 'page', + analytics.trackLink(this, "Clicked download", { + section: $link.closest(".navbar").length ? "header" : "page", pathname: window.location.pathname, - type: $link.hasClass('button') ? 'button' : 'link' - }) - }) + type: $link.hasClass("button") ? "button" : "link", + }); + }); analytics.track( - 'Viewed ' + $.trim(document.title.split('|').shift()) + ' page' - ) - - $('.plugin-plate-link').each(function () { - analytics.trackLink(this, 'Click on plugin', { - plugin_type: $(this).closest('.plugin-plate').find('h3').text() - }) - }) - - $('#documentation .page-navigation a').each(function () { - analytics.trackLink(this, 'Click documentation link', { - documentation_name: $(this).text() - }) - }) - - $('.community-plate a').each(function () { - analytics.trackLink(this, 'Click community link', { - community_type: $.trim($(this).closest('.community-plate').find('h4').text()) - }) - }) - - analytics.trackLink($('a[href="#comparison"]')[0], 'Clicked Why Kong') + "Viewed " + $.trim(document.title.split("|").shift()) + " page" + ); + + $(".plugin-plate-link").each(function () { + analytics.trackLink(this, "Click on plugin", { + plugin_type: $(this).closest(".plugin-plate").find("h3").text(), + }); + }); + + $("#documentation .page-navigation a").each(function () { + analytics.trackLink(this, "Click documentation link", { + documentation_name: $(this).text(), + }); + }); + + $(".community-plate a").each(function () { + analytics.trackLink(this, "Click community link", { + community_type: $.trim( + $(this).closest(".community-plate").find("h4").text() + ), + }); + }); + + analytics.trackLink($('a[href="#comparison"]')[0], "Clicked Why Kong"); // Add Smooth scroll when link with attr clicked $('a[data-link="scroll"]').click(function () { - $('html, body').animate({ - scrollTop: $($.attr(this, 'href')).offset().top - NAV_HEIGHT // Add spacing on top after scroll - }, 600) // Adjust scroll speed + $("html, body").animate( + { + scrollTop: $($.attr(this, "href")).offset().top - NAV_HEIGHT, // Add spacing on top after scroll + }, + 600 + ); // Adjust scroll speed // Remove any active classes that may already be applied - $('a[data-link="scroll"').removeClass('active') + $('a[data-link="scroll"').removeClass("active"); // Add active class sidebar a - $(this).addClass('active') - return false - }) + $(this).addClass("active"); + return false; + }); // Smooth scroll if hash in URL if (window.location.hash) { if ($(window).width() <= 1000) { - var offset = NAV_HEIGHT + 40 + var offset = NAV_HEIGHT + 40; } else { - var offset = NAV_HEIGHT + var offset = NAV_HEIGHT; } - $('html, body').scrollTop(0).show() - $('html, body').animate({ - scrollTop: $(window.location.hash).offset().top - offset // Add spacing on top after scroll - }, 600) // Adjust scroll speed + $("html, body").scrollTop(0).show(); + $("html, body").animate( + { + scrollTop: $(window.location.hash).offset().top - offset, // Add spacing on top after scroll + }, + 600 + ); // Adjust scroll speed } // Plugins filter - $('a[data-filter]').click(function () { - var target = $(this).data('filter') + $("a[data-filter]").click(function () { + var target = $(this).data("filter"); // Remove any active classes that may already be applied - $('a[data-filter]').removeClass('active') + $("a[data-filter]").removeClass("active"); // Add active class sidebar a - $(this).addClass('active') + $(this).addClass("active"); // For all faded cards, replace href with data-href target - $('.plugin-card.fadeOut').each(function () { - var link = $(this).find('a') - link.attr('href', $(link).attr('data-href')) - link.removeAttr('data-href') - }) + $(".plugin-card.fadeOut").each(function () { + var link = $(this).find("a"); + link.attr("href", $(link).attr("data-href")); + link.removeAttr("data-href"); + }); // Remove any fade states that may already be applied - $('.plugin-card').removeClass('fadeOut') + $(".plugin-card").removeClass("fadeOut"); // If the target of the li is not all continue - if (target !== 'all') { + if (target !== "all") { // Fade all cards that don't have matching filter - $('.plugin-card').not('.' + target).addClass('fadeOut') + $(".plugin-card") + .not("." + target) + .addClass("fadeOut"); // For each faded card, move href to data-href and remove href - $('.plugin-card.fadeOut').each(function () { - var link = $(this).find('a') - link.attr('data-href', $(link).attr('href')) - link.removeAttr('href') - }) + $(".plugin-card.fadeOut").each(function () { + var link = $(this).find("a"); + link.attr("data-href", $(link).attr("href")); + link.removeAttr("href"); + }); } - }) + }); // Responsive Tables - if($window.width() <= 1099) { - mobileTable() + if ($window.width() <= 1099) { + mobileTable(); } - $window.resize(function (){ - if($window.width() <= 1099) { - mobileTable() + $window.resize(function () { + if ($window.width() <= 1099) { + mobileTable(); } - }) + }); - function mobileTable () { - $('table').each(function (index, value) { - var headerCount = $(this).find('thead th').length + function mobileTable() { + $("table").each(function (index, value) { + var headerCount = $(this).find("thead th").length; for (i = 0; i <= headerCount; i++) { - var headerLabel = $(this).find('thead th:nth-child(' + i + ')').text() - - $(this).find('tr td:not([colspan]):nth-child(' + i + ')').replaceWith( - function () { - return $('').append($(this).contents()) - }) + var headerLabel = $(this) + .find("thead th:nth-child(" + i + ")") + .text(); + + $(this) + .find("tr td:not([colspan]):nth-child(" + i + ")") + .replaceWith(function () { + return $('').append( + $(this).contents() + ); + }); } - }) + }); } // watch scroll and update active scroll-to anchor links $window.scroll(() => { - const anchors = $('a.header-link') - const scrollToLinks = $('a.scroll-to') + const anchors = $("a.header-link"); + const scrollToLinks = $("a.scroll-to"); if (!anchors.length || !scrollToLinks.length) { - return + return; } - let activeSet = false - scrollToLinks.removeClass('active') + let activeSet = false; + scrollToLinks.removeClass("active"); $(anchors.get().reverse()).each((index, element) => { - const $element = $(element) + const $element = $(element); // window top + header section - if ((window.scrollY + NAV_HEIGHT + 80) >= $element.offset().top) { - $(`a.scroll-to[href$="${$element.attr('href')}"]`).addClass('active') - activeSet = true - return false + if (window.scrollY + NAV_HEIGHT + 80 >= $element.offset().top) { + $(`a.scroll-to[href$="${$element.attr("href")}"]`).addClass("active"); + activeSet = true; + return false; } - }) + }); if (!activeSet) { - scrollToLinks.first().addClass('active') + scrollToLinks.first().addClass("active"); } - }) + }); // navtabs - const navtabs = $('div[data-navtab-id]') + const navtabs = $("div[data-navtab-id]"); navtabs.click(function () { - const navtabTitle = $(this) - const navtabID = navtabTitle.data('navtab-id') - const navtabContent = $(`div[data-navtab-content='${navtabID}']`) + const navtabTitle = $(this); + const navtabID = navtabTitle.data("navtab-id"); + const navtabContent = $(`div[data-navtab-content='${navtabID}']`); if (navtabContent.length === 0) { - console.err(`No navtab content found for navtab=${navtabID}`) - return + console.err(`No navtab content found for navtab=${navtabID}`); + return; } - navtabTitle.siblings().removeClass('active') - navtabTitle.addClass('active') - navtabContent.siblings().css('display', 'none') - navtabContent.css('display', 'block') - }) + navtabTitle.siblings().removeClass("active"); + navtabTitle.addClass("active"); + navtabContent.siblings().css("display", "none"); + navtabContent.css("display", "block"); + }); // set first navtab as active - $('.navtabs').each(function (index, navtabs) { - $(navtabs).find('div[data-navtab-content]').css('display', 'none') + $(".navtabs").each(function (index, navtabs) { + $(navtabs).find("div[data-navtab-content]").css("display", "none"); - const navtabsTabs = $(navtabs).find('div[data-navtab-id]') - navtabsTabs.first().addClass('active') - $(`div[data-navtab-content='${navtabsTabs.first().data('navtab-id')}']`).css('display', 'block') - }) + const navtabsTabs = $(navtabs).find("div[data-navtab-id]"); + navtabsTabs.first().addClass("active"); + $( + `div[data-navtab-content='${navtabsTabs.first().data("navtab-id")}']` + ).css("display", "block"); + }); // feedback widget - function sendFeedback (result, comment = '') { + function sendFeedback(result, comment = "") { $.ajax({ - type: 'POST', - url: 'https://script.google.com/macros/s/AKfycbzA9EgTcX2aEcfHoChlTNA-MKX75DAOt4gtwx9WMcuMBNHHAQ4/exec', - data: JSON.stringify([result, comment, window.location.pathname]) - }) + type: "POST", + url: + "https://script.google.com/macros/s/AKfycbzA9EgTcX2aEcfHoChlTNA-MKX75DAOt4gtwx9WMcuMBNHHAQ4/exec", + data: JSON.stringify([result, comment, window.location.pathname]), + }); - $('.feedback-thankyou').css('visibility', 'visible') + $(".feedback-thankyou").css("visibility", "visible"); setTimeout(() => { - $('#feedback-widget-checkbox').prop('checked', false) - }, 2000) + $("#feedback-widget-checkbox").prop("checked", false); + }, 2000); } - $('#feedback-comment-button-back').click(function () { - $('.feedback-options').css('visibility', 'visible') - $('.feedback-comment').css('visibility', 'hidden') - }) + $("#feedback-comment-button-back").click(function () { + $(".feedback-options").css("visibility", "visible"); + $(".feedback-comment").css("visibility", "hidden"); + }); - $('#feedback-comment-button-submit').click(function () { - $('.feedback-comment').css('visibility', 'hidden') - sendFeedback('no', $('#feedback-comment-text').val()) - }) + $("#feedback-comment-button-submit").click(function () { + $(".feedback-comment").css("visibility", "hidden"); + sendFeedback("no", $("#feedback-comment-text").val()); + }); - $('.feedback-options-button').click(function () { - const button = $(this) - const result = button.data('feedback-result') + $(".feedback-options-button").click(function () { + const button = $(this); + const result = button.data("feedback-result"); - $('.feedback-options').css('visibility', 'hidden') - if (result === 'yes') { - sendFeedback('yes') + $(".feedback-options").css("visibility", "hidden"); + if (result === "yes") { + sendFeedback("yes"); } else { - $('.feedback-comment').css('visibility', 'visible') + $(".feedback-comment").css("visibility", "visible"); } - }) + }); /** * Copy code snippet support @@ -569,63 +622,73 @@ $(function () { * data-copy-code="{custom-code}" - (optional) can be used to specify {custom-code} to be copied (only single-line text is supported) * */ - const copyInput = $('') - $('body').append(copyInput) - - $('.copy-code-snippet, pre > code').each(function (index, element) { - function findSnippetElement () { - const $code = $(element) - let snippet = $code.parent('pre').parent('.highlight').parent('.highlighter-rouge') + const copyInput = $(''); + $("body").append(copyInput); + + $(".copy-code-snippet, pre > code").each(function (index, element) { + function findSnippetElement() { + const $code = $(element); + let snippet = $code + .parent("pre") + .parent(".highlight") + .parent(".highlighter-rouge"); if (snippet.length > 0) { - return snippet + return snippet; } - snippet = $code.parent('pre').parent('.highlight') + snippet = $code.parent("pre").parent(".highlight"); if (snippet.length > 0) { - return snippet + return snippet; } - snippet = $code.parent('pre') + snippet = $code.parent("pre"); if (snippet.length > 0) { - return snippet + return snippet; } - return $code + return $code; } - const noCode = $('div.page.no-copy-code').length > 0 - const snippet = findSnippetElement() + const noCode = $("div.page.no-copy-code").length > 0; + const snippet = findSnippetElement(); - if (!snippet.hasClass('copy-code-snippet') && noCode) { - return + if (!snippet.hasClass("copy-code-snippet") && noCode) { + return; } - snippet.addClass('copy-code-snippet') + snippet.addClass("copy-code-snippet"); - const action = $('') + const action = $(''); action.click(function () { - if ($('#copy-code-success-info').length > 0) { - return + if ($("#copy-code-success-info").length > 0) { + return; } - copyInput.text(snippet.data('copy-code') || snippet.find('code').text().replace(/^\s*\$\s*/gi, '')) - copyInput.select() - document.execCommand('copy') - - const successInfo = $('
Copied to clipboard!
') - successInfo - .css({ - top: action[0].getBoundingClientRect().top - action.height(), - left: action[0].getBoundingClientRect().left + action.width() / 2, - opacity: 1 - }) + copyInput.text( + snippet.data("copy-code") || + snippet + .find("code") + .text() + .replace(/^\s*\$\s*/gi, "") + ); + copyInput.select(); + document.execCommand("copy"); + + const successInfo = $( + '
Copied to clipboard!
' + ); + successInfo.css({ + top: action[0].getBoundingClientRect().top - action.height(), + left: action[0].getBoundingClientRect().left + action.width() / 2, + opacity: 1, + }); setTimeout(function () { successInfo.animate({ opacity: 0 }, function () { - successInfo.remove() - }) - }, 1000) - $('body').append(successInfo) - }) - snippet.append(action) - }) + successInfo.remove(); + }); + }, 1000); + $("body").append(successInfo); + }); + snippet.append(action); + }); /** * Expandable images @@ -644,61 +707,69 @@ $(function () { * disable_image_expand: true * --- */ - const imageModal = $('#image-modal') + const imageModal = $("#image-modal"); - function closeModal () { - $(document.body).removeClass('image-modal-no-scroll') - imageModal.removeClass('visible') - document.removeEventListener('keydown', imageModalKeyDown) + function closeModal() { + $(document.body).removeClass("image-modal-no-scroll"); + imageModal.removeClass("visible"); + document.removeEventListener("keydown", imageModalKeyDown); } - function imageModalKeyDown (e) { - if (e.key === 'Escape') { - closeModal() + function imageModalKeyDown(e) { + if (e.key === "Escape") { + closeModal(); } } - if (imageModal.length > 0 && !imageModal.data('image-expand-disabled')) { - imageModal.find('i').click(closeModal) - imageModal.find('.image-modal-backdrop').click(closeModal) + if (imageModal.length > 0 && !imageModal.data("image-expand-disabled")) { + imageModal.find("i").click(closeModal); + imageModal.find(".image-modal-backdrop").click(closeModal); - $('.page-content > .content img:not(.no-image-expand)').each(function (index, img) { - const $img = $(img) + $(".page-content > .content img:not(.no-image-expand)").each(function ( + index, + img + ) { + const $img = $(img); - img.style.cursor = 'pointer' + img.style.cursor = "pointer"; $img.click(function () { - $(document.body).addClass('image-modal-no-scroll') - imageModal.addClass('visible') - imageModal.find('img').attr('src', $img.attr('src')) + $(document.body).addClass("image-modal-no-scroll"); + imageModal.addClass("visible"); + imageModal.find("img").attr("src", $img.attr("src")); - document.addEventListener('keydown', imageModalKeyDown) - }) - }) + document.addEventListener("keydown", imageModalKeyDown); + }); + }); } // open docs sidebar items - $('.docs-sidebar a.active, li.accordion-item.active').each(function (index, a) { - $(a).parents('li.accordion-item').each(function (index, item) { - $(item).addClass('active') - $(item).find('> input').prop('checked', true) - }) - }) - - const scrollToTopButton = $('#scroll-to-top-button') - - function updateScrollToTopButttonVisibility () { + $(".docs-sidebar a.active, li.accordion-item.active").each(function ( + index, + a + ) { + $(a) + .parents("li.accordion-item") + .each(function (index, item) { + $(item).addClass("active"); + $(item).find("> input").prop("checked", true); + }); + }); + + const scrollToTopButton = $("#scroll-to-top-button"); + + function updateScrollToTopButttonVisibility() { if ($window.scrollTop() >= $window.height()) { - scrollToTopButton.addClass('visible') + scrollToTopButton.addClass("visible"); } else { - scrollToTopButton.removeClass('visible') + scrollToTopButton.removeClass("visible"); } } scrollToTopButton.click(function () { - $('html, body').animate({ scrollTop: 0 }, 'slow') - }) - updateScrollToTopButttonVisibility() - $window.on('scroll', updateScrollToTopButttonVisibility) + $("html, body").animate({ scrollTop: 0 }, "slow"); + }); + updateScrollToTopButttonVisibility(); + $window.on("scroll", updateScrollToTopButttonVisibility); /** * Custom table column widths in markdown files @@ -709,16 +780,16 @@ $(function () { * |-----------------|-------------|-------------------| * */ - const WIDTH_REGEX = /(.*)\s*{:width=(.+):}/ - $('table thead tr th').each(function (index, th) { - const $th = $(th) + const WIDTH_REGEX = /(.*)\s*{:width=(.+):}/; + $("table thead tr th").each(function (index, th) { + const $th = $(th); - const match = WIDTH_REGEX.exec($th.text()) + const match = WIDTH_REGEX.exec($th.text()); if (match) { - $th.text(match[1]) - th.style.width = match[2] + $th.text(match[1]); + th.style.width = match[2]; } - }) + }); /** * Edition based element visibility @@ -750,25 +821,69 @@ $(function () { * url: /expose-services * edition: community */ - const edition = decodeURIComponent(window.location.search).substring(1) - .split('&') - .map(queryParam => queryParam.split('=')) - .filter(params => params[0] === 'edition') - .map(params => params[1])[0] - - const editionSwitch = $('.edition-switch') + const edition = decodeURIComponent(window.location.search) + .substring(1) + .split("&") + .map((queryParam) => queryParam.split("=")) + .filter((params) => params[0] === "edition") + .map((params) => params[1])[0]; + + const editionSwitch = $(".edition-switch"); editionSwitch.click(function () { - if (edition === 'community') { - window.location.search = '?edition=enterprise' + if (edition === "community") { + window.location.search = "?edition=enterprise"; } else { - window.location.search = '?edition=community' + window.location.search = "?edition=community"; } - }) + }); if (edition) { - $('*[data-edition]').not(`[data-edition="${edition}"]`).each(function (index, element) { - element.style.display = 'none' - }) - editionSwitch.addClass(edition) + $("*[data-edition]") + .not(`[data-edition="${edition}"]`) + .each(function (index, element) { + element.style.display = "none"; + }); + editionSwitch.addClass(edition); + } +}); + +jQuery(document).ready(function () { + var closed = localStorage.getItem("closebanner-survey"); + console.log(closed); + var getUrl = window.location; + var baseUrl = + getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split("/")[0]; + if ( + closed !== "closeme" && + window.location.href.indexOf("getting-started") === -1 && + window.location.href.indexOf("2.1.x") > -1 && + getUrl !== baseUrl + ) { + $("header.navbar").removeClass("closed"); + $("body").addClass("banner"); + } else { + $("header.navbar").addClass("closed"); + $("body").removeClass("banner"); + } +}); + +var scrolling = false; +$(document).scroll(function () { + scrolling = true; +}); + +setInterval(function () { + if (scrolling) { + scrolling = false; + if ($(document).scrollTop() < 85) { + $("header").removeClass("compress"); + } else { + $("header").addClass("compress"); + } } -}) +}, 10); + +$(".closebanner").click(function () { + $("header.navbar").addClass("closed"); + localStorage.setItem("closebanner-survey", "closeme"); +}); diff --git a/app/_assets/stylesheets/base.less b/app/_assets/stylesheets/base.less index e99614eeb78e..ac3c80ecc940 100644 --- a/app/_assets/stylesheets/base.less +++ b/app/_assets/stylesheets/base.less @@ -140,9 +140,9 @@ strong { code { padding: 4px; - color: @red; + color: @gray-darker; font-size: 14px; - background-color: #fff2f2; + background-color: #f5f5f5; border-radius: 3px; border: 0 none; margin: 0; diff --git a/app/_assets/stylesheets/cookie-policy.less b/app/_assets/stylesheets/cookie-policy.less index 97fdef3e6675..95a4eecb21f8 100644 --- a/app/_assets/stylesheets/cookie-policy.less +++ b/app/_assets/stylesheets/cookie-policy.less @@ -6,7 +6,7 @@ border-radius: 3px; box-shadow: 0 15px 35px rgba(50,50,93,.1), 0 5px 15px rgba(0,0,0,.07); background: #fff; - z-index: 10; + z-index: 15; p { color: rgba(0,0,0,.7); diff --git a/app/_assets/stylesheets/footer.less b/app/_assets/stylesheets/footer.less index bbfc0686cd92..deefe94a3416 100644 --- a/app/_assets/stylesheets/footer.less +++ b/app/_assets/stylesheets/footer.less @@ -32,13 +32,14 @@ padding: @gutter-flex-2x 0 0; .form iframe { - min-height: 60px; + min-height: 50px; min-width: 500px; + transform: translateY(-12.5px); } @media (max-width: 480px) { .form iframe { - min-height: 190px; + min-height: 110px; min-width: 0px; } } @@ -50,6 +51,13 @@ &.newsletter { overflow: hidden; + @media (max-width: 992px) and (min-width: 630px) { + > li { + &:nth-of-type(2) { + padding-top: 62.5px; + } + } + } } @media (min-width: @grid-width-xs) { @@ -64,39 +72,6 @@ > li { font-family: Roboto, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; - .social-link { - width: auto; - min-width: auto; - display: inline-block; - float: left; - a:not(.btn-gh), - i { - color: #999; - font-size: 20px; - margin-right: 5px; - } - a.btn-gh { - padding: 2px 5px; - color: #333; - text-decoration: none; - text-shadow: 0 1px 0 #fff; - font: 700 11px/14px "Helvetica Neue", Helvetica, Arial, sans-serif; - cursor: pointer; - border-radius: 3px; - border: 1px solid #d5d5d5; - background-color: #eee; - background-image: linear-gradient(to bottom, #fcfcfc 0, #eee 100%); - font-size: 11px; - color: #999; - display: inline-block; - margin-top: 6px; - i { - color: #999; - margin-right: 0px; - font-size: 14px; - } - } - } #subscription_form .error-message.message { display: inline-block; @@ -159,11 +134,11 @@ } } h5 { - color: #062f4d; + color: #7d91b3; + -webkit-transform: none; + transform: none; font-size: 16px; - font-weight: 500; - letter-spacing: 0.5px; - text-transform: none; + font-weight: 600; margin-bottom: 1rem; font-family: Roboto, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; @@ -172,13 +147,14 @@ font-size: 15px; span { display: inline-block; - padding: 2.5px 7.5px; + padding: 5px 7.5px; margin-left: 5px; color: #008aeb; background: #d0eaff; border-radius: 5px; font-weight: 400; font-size: 12px; + line-height: 1; text-transform: uppercase; } } @@ -186,6 +162,20 @@ &.logo-wrapper { min-width: 350px; + p { + color: #000; + font-size: 14px; + margin-bottom: 0; + } + ul { + display: inline-block; + width: 100%; + li { + display: inline-block; + width: 50%; + float: left; + } + } } @media (max-width: 960px) { @@ -215,11 +205,50 @@ &:not(.logo-wrapper) { padding-left: 3rem; flex-basis: 0%; + padding-top: 62.5px; } } @media (min-width: @grid-width-lg) { .flex-col(1, 1, 2); } + @media (max-width: 992px) { + .flex-col(1, 1, 3); + &.logo-wrapper { + flex-basis: 66%; + padding-left: 3rem; + max-width: 66%; + min-width: 66%; + } + &:not(.logo-wrapper) { + padding-left: 3rem; + flex-basis: 0%; + padding-top: 0px; + min-width: 33%; + } + } + @media (max-width: 630px) { + a { + font-size: 12px; + span { + display: none; + } + } + &.logo-wrapper { + min-width: 100%; + padding-left: 0; + ul { + margin-bottom: 0; + } + } + &:not(.logo-wrapper) { + min-width: 50%; + padding-top: 0; + margin-bottom: 0; + padding-left: 0; + padding-right: 0.5rem; + box-sizing: border-box; + } + } } } } @@ -247,9 +276,10 @@ } img { width: 100%; - max-width: 100%; + max-width: 45px; max-height: 100%; border: 0; + margin-bottom: 10px; } } @@ -343,8 +373,90 @@ .legal { padding: 0rem 0 1rem; - background: #fff; - + .container { + max-width: 100%; + padding: 0 2em; + @media (max-width: 600px) { + flex-wrap: wrap; + } + > div { + float: left; + position: absolute; + top: 50%; + left: 16px; + transform: translate(0, -50%); + color: #004b80; + @media (max-width: 600px) { + position: relative; + width: 100%; + text-align: center; + transform: none; + left: auto; + right: auto; + top: auto; + min-width: 100%; + &.social { + min-width: 0px; + width: auto; + display: block; + margin: 10px auto 0; + } + } + @media (max-width: 768px) { + left: 0; + } + &:not(.social) { + left: auto; + right: 16px; + @media (max-width: 768px) { + right: 0; + } + } + } + } + @media (min-width: 1279px) { + .container { + width: 1250px; + } + } + @media (min-width: 1379px) { + .container { + width: 1320px; + } + } + .social-link { + width: auto; + min-width: auto; + display: inline-block; + float: left; + a:not(.btn-gh), + i { + color: #7d91b3; + font-size: 20px; + margin-right: 5px; + } + a.btn-gh { + padding: 2px 5px; + color: #333; + text-decoration: none; + text-shadow: 0 1px 0 #fff; + font: 700 11px/14px "Helvetica Neue", Helvetica, Arial, sans-serif; + cursor: pointer; + border-radius: 3px; + border: 1px solid #d5d5d5; + background-color: #eee; + background-image: linear-gradient(to bottom, #fcfcfc 0, #eee 100%); + font-size: 11px; + color: #999; + display: inline-block; + margin-top: 6px; + i { + color: #999; + margin-right: 0px; + font-size: 14px; + } + } + } ul { .flex-row(); list-style: none; @@ -416,7 +528,7 @@ [class^="marketing-footer"][class*="--light-gray"] { border-top: solid 1px #ccc; background-color: #fff; - + overflow: hidden; section { padding-top: 0 !important; } @@ -426,7 +538,8 @@ color: @color-dark-blend-strong; } a { - color: @color-dark-blend-strong; + color: #004b80; + font-weight: 400; } h4:after { border-bottom-color: @green; @@ -439,14 +552,14 @@ } .legal { - background-color: #fff; - color: @black-70; + background: #f7f9fc; + color: #004b80; ul { text-align: center; a { - color: #000; + color: #004b80; } } } diff --git a/app/_assets/stylesheets/header.less b/app/_assets/stylesheets/header.less index 4d494dafd4fc..8746cb4e467d 100644 --- a/app/_assets/stylesheets/header.less +++ b/app/_assets/stylesheets/header.less @@ -19,6 +19,129 @@ body { max-width: 100%; } + #promo-banner { + display: none; + } + + @media (min-width: 1080px) { + body.banner { + #promo-banner { + position: fixed; + display: block; + top: 0; + width: 100vw; + height: 37.5px; + max-height: 37.5px; + left: 0; + z-index: 9; + padding-top: 1.5px; + top: 0px; + overflow: hidden; + background: #efefef; + box-shadow: inset 0 -10px 40px -20px rgba(0, 0, 0, 0.25); + h4.countdown { + display: inline-block; + } + h4.flip { + display: none; + } + &.flip { + h4.countdown { + display: none; + } + h4.flip { + display: inline-block; + } + } + .closebanner { + position: absolute; + height: 14px; + width: 14px; + z-index: 11; + left: 0; + top: 10px; + opacity: 1; + cursor: pointer; + transition: 0.2s ease-in-out; + &:hover { + box-shadow: 0 0 0 2px #0037ff; + opacity: 1; + } + &:before { + content: ""; + background: linear-gradient( + 45deg, + transparent calc(50% - 1px), + #0037ff calc(50% - 1px), + #0037ff calc(50% + 1px), + transparent calc(50% + 1px) + ), + linear-gradient( + -45deg, + transparent calc(50% - 1px), + #0037ff calc(50% - 1px), + #0037ff calc(50% + 1px), + transparent calc(50% + 1px) + ); + position: absolute; + width: 100%; + height: 100%; + z-index: 1; + top: 0; + left: 0; + border-radius: 100%; + cursor: pointer; + } + } + .container { + text-align: center; + h4 { + span { + font-size: 14px; + color: #222; + display: inline-block; + font-weight: 400; + a { + color: #0037ff; + font-weight: 900; + display: inline-block; + margin-left: 10px; + &:hover { + color: #004b80; + &:after { + transform: translateX(2.5px); + } + } + &:after { + content: "\f0da"; + font-family: FontAwesome, "FontAwesome", "Font Awesome"; + display: inline-block; + margin-left: 5px; + transition: 0.2s ease-in-out; + } + } + } + } + } + } + + header:not(.closed) #promo-banner ~ .container { + margin-top: 5px; + text-align: center; + } + + header:not(.closed) ~ div.page, + header.navbar { + padding-top: 40px; + transition: transform 0.3s ease-in-out; + &.closed, + &.compress { + transform: translateY(-40px) !important; + } + } + } + } + .nav-link:focus, .nav-link:hover, .navbar-brand:focus, @@ -256,7 +379,7 @@ body { -webkit-outline: none; outline: 0; margin-top: 0; - top: calc(50% - 13px); + top: calc(50% - 16px); } .kong-navbar .navbar-toggler div { position: absolute; @@ -383,6 +506,14 @@ body { border-top: none; padding-bottom: 2rem; } + nav.navbar.full-width + .kong-navbar_nav + #menu-primary-nav + .multicol + > ul.sub-menu + > li:first-of-type { + background: #fff; + } .navbar.full-width .menu li.multicol.wide.toplabel > ul.sub-menu { min-width: 840px; padding-top: 1.5rem; @@ -429,23 +560,18 @@ body { } } body header.navbar { - padding-top: 35px; - -webkit-transform: translateY(-22.5px) !important; - transform: translateY(-22.5px) !important; - transition: 0.2s ease-in-out; + padding-top: 0px; } @media (max-width: 768px) { .kong-navbar .navbar-toggler { right: 10px; } } - body header.navbar.expand { + body header.navbar.expand:not(.closed) { -webkit-transform: translateY(0) !important; transform: translateY(0) !important; } body header.navbar.lower_nav { - -webkit-transform: translateY(-37.5px) !important; - transform: translateY(-37.5px) !important; box-shadow: 0 10px 20px -12.5px rgba(0, 0, 0, 0.15); background: #fff !important; max-height: 92px !important; @@ -508,6 +634,7 @@ body { .navbar.full-width .kong-navbar_nav #menu-primary-nav > li > a { padding-left: 0; padding-right: 0; + padding-bottom: 14px; } .navbar.full-width .kong-navbar_nav #menu-primary-nav > li.demo-btn { color: #17a956; @@ -557,10 +684,12 @@ body { } > li.demo-btn { a { - color: #17a956; - padding: 2.5px 8px; - border: 1px solid; + color: #1155cb; + padding: 8px 23px; + border: 1px solid #a6c6ff; + border-radius: 5px; transition: 0.2s ease-in-out; + transform: translateY(-5px); &:hover { color: #fff; background: #17a956; @@ -754,6 +883,9 @@ body { &:last-of-type { background: #f4f9ff; } + &:first-of-type { + background: #fff; + } padding-bottom: 12px; > a { width: 17.5%; @@ -1296,11 +1428,11 @@ body { } .navbar.full-width.mobile-triggers { width: 100vw; - height: calc(200vh - 92px); + height: calc(200vh - 58px); position: fixed; background: transparent; left: 0; - top: 92px; + top: 58px; padding: 0; visibility: hidden; overflow: hidden; diff --git a/app/_assets/stylesheets/navtabs.less b/app/_assets/stylesheets/navtabs.less index 6d839d273ad1..22acc2d409dd 100644 --- a/app/_assets/stylesheets/navtabs.less +++ b/app/_assets/stylesheets/navtabs.less @@ -1,4 +1,6 @@ .navtabs { + margin-top: 1.5rem; + .navtab-titles { display: flex; align-items: center; @@ -36,6 +38,6 @@ } .navtab-contents { - padding: 24px 0; + padding: 1.5rem 0 0 0; } } diff --git a/app/_assets/stylesheets/page.less b/app/_assets/stylesheets/page.less index 387fd2e97422..37e94b7de794 100644 --- a/app/_assets/stylesheets/page.less +++ b/app/_assets/stylesheets/page.less @@ -39,7 +39,6 @@ } .search-version-row { - #version-dropdown { width: auto; padding: 0 16px; @@ -158,7 +157,11 @@ &:not(.homepage) { .page-header { - background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), #effeff); + background-image: linear-gradient( + to bottom, + rgba(255, 255, 255, 0), + #effeff + ); padding-bottom: 12px; .container { @@ -295,7 +298,9 @@ padding: 25px 0; } - h1, p, .page-header-section-title { + h1, + p, + .page-header-section-title { margin: 0; } @@ -407,12 +412,17 @@ left: 50%; top: 0; bottom: 0; - min-width: 1500px; + max-width: 100%; background-size: cover; - background-image: linear-gradient(to bottom, #ffffff, 40%, transparent), url("/assets/images/docs/banner-bkg.png"); - background-image: -moz-linear-gradient(bottom, rgba(255,255,255,0) 40%, #ffffff), url("/assets/images/docs/banner-bkg.png"); + background-image: linear-gradient(to bottom, #ffffff, 40%, transparent), + url("/assets/images/docs/banner-bkg.png"); + background-image: -moz-linear-gradient( + bottom, + rgba(255, 255, 255, 0) 40%, + #ffffff + ), + url("/assets/images/docs/banner-bkg.png"); transform: translateX(-50%); - } } @@ -443,7 +453,7 @@ &:before, &:after { - content: ''; + content: ""; position: absolute; height: 4px; width: 100%; @@ -469,7 +479,7 @@ right: 0; padding: 25px; height: ~"calc(100% - 80px)"; - box-shadow: 0px 12px 15px rgba(0, 0, 0, .15); + box-shadow: 0px 12px 15px rgba(0, 0, 0, 0.15); border: 0 none; background: #fff; overflow: scroll; @@ -488,7 +498,8 @@ } nav { - h5, a { + h5, + a { font-size: 15px; } } @@ -508,6 +519,10 @@ li { line-height: 26px; + + a { + color: #85898c; + } } li ul { @@ -519,16 +534,29 @@ } li a.active { - color: @blue; + color: @gray-darker; + font-weight: 600; + opacity: 1; } a { font-size: 14px; + color: @blue; + + &:hover { + opacity: 0.5; + } } .fa { color: #acb7bf; } + + table { + a { + color: @blue; + } + } } .toggles { @@ -625,17 +653,27 @@ } } - p, h1, h2, h3, h4, h5, h6 { + p, + h1, + h2, + h3, + h4, + h5, + h6 { .font-source-sans(); color: #505659; } - h1, h2, h3, h4 { + h1, + h2, + h3, + h4 { margin-bottom: 1em; font-weight: 600; } - h2, h3 { + h2, + h3 { font-weight: 600; color: #262e33; } @@ -644,7 +682,7 @@ font-size: 34px; color: #262e33; margin-top: 2em; - margin-bottom: .9em; + margin-bottom: 0.9em; } .alert + h1 { @@ -654,22 +692,22 @@ h2 { font-size: 30px; margin-top: 2em; - margin-bottom: .8em; + margin-bottom: 0.8em; } h3 { margin-top: 1.5em; - margin-bottom: .7em; + margin-bottom: 0.7em; } h4 { margin-top: 1.3em; - margin-bottom: .7em; + margin-bottom: 0.7em; } h5 { margin-top: 1.2em; - margin-bottom: .8em; + margin-bottom: 0.8em; } > h1:first-child, @@ -701,15 +739,18 @@ } } - p, figure { + p, + figure { margin-bottom: 1em; } a { text-decoration: none; + color: @blue; &:hover { text-decoration: underline; + opacity: 0.7; } } @@ -743,17 +784,35 @@ line-height: 24px; margin: 1.3em 0; padding: 12px 17px; - border-radius: 4px; + border-radius: 3px; + max-height: 400px; + overflow: auto; + + &::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + &::-webkit-scrollbar-thumb:hover { + background-color: rgba(0,0,0,0.25); + } + + &::-webkit-scrollbar-thumb { + background-color: @gray; + outline: 1px solid @gray; + } + + &::-webkit-scrollbar-corner { + background-color: @gray-light; + border-right: 1px solid @gray; + border-radius: 3px; + } code { padding: 0; color: #000; background: transparent; } - - &:hover { - overflow: auto; - } } blockquote { @@ -769,12 +828,15 @@ Generic Styling for Desktop table { display: block; max-width: 100%; - border-collapse: collapse; font-size: 14px; overflow-x: auto; + border: none; + border-collapse: collapse; + margin-top: 1.5em; code { white-space: normal; + font-size: 13px; } } @@ -782,23 +844,30 @@ Generic Styling for Desktop font-size: 14px; } - /* Zebra striping */ - - tr:nth-of-type(odd) { - background: @gray-light; + tr, th, td { + border: none; } th { - font-weight: bold; + font-weight: 600; + color: @black-80; + background-color: @grey-100; } - td, th { - padding: 6px; - border: 1px solid #ccc; + td, + th { + padding: 8px 16px 8px; + border-bottom: 1px solid @grey-300; + border-top: 1px solid @grey-300; } @media only screen and (max-width: 1099px) { - table, thead, tbody, th, td, tr { + table, + thead, + tbody, + th, + td, + tr { display: block; text-align: left; } @@ -811,13 +880,14 @@ Generic Styling for Desktop } tr { - border: 1px solid #ccc; + border-top: 1px solid @grey-300; + border-bottom: 1px solid @grey-300; } td { /* Behave like a "row" */ border: none; - border-bottom: 1px solid #eee; + border-bottom: 1px solid @grey-300; position: relative; } @@ -827,7 +897,7 @@ Generic Styling for Desktop content: attr(data-label); font-size: 14px; - + font-weight: 600; } } } @@ -939,16 +1009,16 @@ Generic Styling for Desktop .install-text { font-size: 14px; line-height: 20px; - color: rgba(0, 0, 0, .85); + color: rgba(0, 0, 0, 0.85); font-weight: 900; - transition: .2s ease-in-out; + transition: 0.2s ease-in-out; display: block; } .install-description { font-size: 12px; - color: rgba(0, 0, 0, .85); - transition: .2s ease-in-out; + color: rgba(0, 0, 0, 0.85); + transition: 0.2s ease-in-out; margin-top: 10px; } @@ -968,7 +1038,7 @@ Generic Styling for Desktop } @media (max-width: 1200px) { - grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));; + grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); } } @@ -1107,39 +1177,46 @@ Generic Styling for Desktop } .alert { - border: 1px solid @gray; - border-radius: 4px; + border: none; + border-left: 3px solid @gray; + border-radius: 0; font-size: 18px; padding: 8px 13px; + + pre, code { + background-color: #fff; + border: none; +} + } .alert-info { color: #757575; - border-color: #e0e0e0; + border-left: 3px solid #e0e0e0; background-color: #f9f9f9; &.blue { - color: #004A80; - border: none; - background-color: #EDF7FF; + color: #004a80; + border-left: 3px solid #004b80; + background-color: #edf7ff; } } .alert-success { color: #3dcc3d; - border-color: #c0eac0;; + border-left: 3px solid #c0eac0; background-color: #f4fff4; } .alert-warning { color: #808060; - border-color: #e0e0c9; + border-left: 3px solid #e0e0c9; background-color: #fffff7; } .alert-danger { color: #cc3d3d; - border-color: #eac0c0; + border-left: 3px solid #eac0c0; background-color: #fff4f4; } @@ -1179,7 +1256,8 @@ Generic Styling for Desktop padding: 2px 8px; margin-right: 12px; border-radius: 11px; - font-family: Roboto, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + font-family: Roboto, -apple-system, system-ui, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size: 10px; font-weight: bold; background: @blue; @@ -1202,8 +1280,8 @@ Generic Styling for Desktop } code { - font-size: 13px; - } + font-size: 13px; + } p { padding: 0 25px 0 75px; @@ -1247,7 +1325,7 @@ Generic Styling for Desktop margin: 0; &:after { - content: ' \203a'; + content: " \203a"; } } @@ -1302,7 +1380,7 @@ Generic Styling for Desktop color: #fff; float: left; margin-right: 10px !important; - background: rgba(255, 255, 255, .2); + background: rgba(255, 255, 255, 0.2); justify-content: center; display: flex; } @@ -1368,7 +1446,7 @@ Generic Styling for Desktop input[type="text"] { border-radius: 3px; - border: 2px solid rgba(0, 0, 0, .1); + border: 2px solid rgba(0, 0, 0, 0.1); width: 100%; height: 40px; padding-left: 12px; @@ -1393,7 +1471,8 @@ Generic Styling for Desktop color: @white-90; letter-spacing: 1px; - &:hover, &:focus { + &:hover, + &:focus { background-color: @green; color: @white-90; } @@ -1405,7 +1484,8 @@ Generic Styling for Desktop margin-bottom: 15px; } - .newsletter-icon, .hidden-sm-down { + .newsletter-icon, + .hidden-sm-down { display: none; } } @@ -1432,11 +1512,10 @@ Generic Styling for Desktop border: 1px solid @navy-dark; border-radius: 50%; - transform: translateX(0vw) translateZ(0) scale(1.0, 1.0); + transform: translateX(0vw) translateZ(0) scale(1, 1); transition: background-size 0.3s, - transform 0.3s cubic-bezier(.16, .22, .22, 1.7), - opacity 0.3s, - box-shadow 0.3s; + transform 0.3s cubic-bezier(0.16, 0.22, 0.22, 1.7), opacity 0.3s, + box-shadow 0.3s; &:hover { box-shadow: 0px 6px 13px 3px rgba(0, 0, 0, 0.5); @@ -1461,7 +1540,7 @@ Generic Styling for Desktop } &::before { - content: 'Chat with Kong Developers'; + content: "Chat with Kong Developers"; display: block; position: relative; width: 200px; @@ -1486,14 +1565,14 @@ Generic Styling for Desktop } &::after { - content: '\f00d'; + content: "\f00d"; display: block; position: absolute; width: 100%; height: 100%; top: 0; left: 0; - font-family: 'FontAwesome'; + font-family: "FontAwesome"; font-size: 0; text-align: center; line-height: 46px; @@ -1526,8 +1605,8 @@ Generic Styling for Desktop #scroll-to-top-button { position: fixed; - bottom: 12px; - right: 24%; + bottom: 45px; + right: 100px; z-index: 10; cursor: pointer; background: #e3e3e3; @@ -1551,7 +1630,7 @@ Generic Styling for Desktop transform: translateY(0); } - @media (max-width: 600px) { + @media (max-width: 800px) { right: 50%; } } diff --git a/app/_assets/stylesheets/pages/docs.less b/app/_assets/stylesheets/pages/docs.less index 582feb93081f..ec631fe007a8 100644 --- a/app/_assets/stylesheets/pages/docs.less +++ b/app/_assets/stylesheets/pages/docs.less @@ -90,16 +90,36 @@ .content { ol { padding-left: 2rem; + counter-reset: base; + + li { + p { + font-size: inherit; + } + } + } + + ol > li::before { + counter-increment: base; + content: counter(base); + font-size: 13px; } ul { // avoid nested lists and lists elements to have smaller and smaller // font sizes font-size: inherit; + margin-left: 0.5rem; + list-style: none; li { // avoid ridiculously big spaces between lists elements margin-bottom: 0.2rem; + list-style-type: disc; + + p { + font-size: inherit; + } } ul { @@ -123,19 +143,19 @@ // titles proportions overridden from base.less h2 { - margin-top: 3rem; + margin-top: 3.2rem; margin-bottom: 1rem; - font-size: 3.5rem; - font-weight: 400; + font-size: 3.2rem; + font-weight: 500; } h3 { - font-size: 2.5rem; - font-weight: 300; + font-size: 2.4rem; + font-weight: 400; } h4 { - font-size: 2.2rem; + font-size: 2rem; font-weight: 300; } diff --git a/app/_assets/stylesheets/pages/extension.less b/app/_assets/stylesheets/pages/extension.less index 22e50a098d23..972b54b129b8 100644 --- a/app/_assets/stylesheets/pages/extension.less +++ b/app/_assets/stylesheets/pages/extension.less @@ -53,6 +53,23 @@ h2, h4, p .highlight { margin: 0 0 2.5rem 0; } + + ol, ul { + li { + p { + font-size: inherit; + } + } + } + + ul { + margin-left: 0.5rem; + + li { + list-style-type: disc; + } + } + table { p { font-size: 14px; @@ -70,7 +87,7 @@ &.blue { color: #004A80; - border: none; + border-left: 3px solid #004b80; background-color: #EDF7FF; } } diff --git a/app/_assets/stylesheets/variables.less b/app/_assets/stylesheets/variables.less index 441e85593b6b..dabccdbfbf4b 100644 --- a/app/_assets/stylesheets/variables.less +++ b/app/_assets/stylesheets/variables.less @@ -113,3 +113,48 @@ @grid-width-md: 768px; @grid-width-lg: 992px; @grid-width-xl: 1095px; + + +// Kongponents colors +// ------------------------- + +@blue-100: #f0f5ff; +@blue-200: #d9e7ff; +@blue-300: #a6c6ff; +@blue-400: #5996ff; +@blue-500: #1456cb; +@blue-600: #083c99; +@blue-700: #0a2b66; + +@steal-100: #f0f4fa; +@steal-200: #dae3f2; +@steal-300: #a3b6d9; +@steal-400: #7d91b3; +@steal-500: #5c7299; +@steal-600: #395380; +@steal-700: #273c61; + +@red-100: #fff7f9; +@red-200: #ffe6ea; +@red-300: #ffb3bf; +@red-400: #f26d83; +@red-500: #e6173a; +@red-600: #bf1330; +@red-700: #99001a; + +@green-100: #f1fff7; +@green-200: #ccffe1; +@green-300: #82d9a6; +@green-400: #19a654; +@green-500: #008036; + +@yellow-100: #fff9e6; +@yellow-200: #ffedb9; +@yellow-300: #ffdc73; +@yellow-400: #f2a230; +@yellow-500: #8c5200; + +@grey-100: #fafafa; +@grey-200: #ebebeb; +@grey-300: #e0e0e0; +@grey-400: #d6d6d6; diff --git a/app/_data/docs_nav_2.2.x.yml b/app/_data/docs_nav_2.2.x.yml new file mode 100644 index 000000000000..c8efba5252d5 --- /dev/null +++ b/app/_data/docs_nav_2.2.x.yml @@ -0,0 +1,468 @@ +# Generated via autodoc-nav +- title: Getting Started + icon: /assets/images/icons/documentation/icn-quickstart-color.svg + items: + - text: Overview + url: /../../getting-started-guide/latest/overview + - text: Prepare to Administer + url: /../../getting-started-guide/latest/prepare + - text: Expose your Services + url: /../../getting-started-guide/latest/expose-services + - text: Protect your Services + url: /../../getting-started-guide/latest/protect-services + - text: Improve Performance + url: /../../getting-started-guide/latest/improve-performance + - text: Secure Services + url: /../../getting-started-guide/latest/secure-services + - text: Set Up Intelligent Load Balancing + url: /../../getting-started-guide/latest/load-balancing + +- title: Guides & References + icon: /assets/images/icons/documentation/icn-references-color.svg + items: + - text: Quickstart Guide + url: /getting-started/introduction + items: + - text: Five-minute quickstart + url: /getting-started/quickstart + + - text: Configuring a Service + url: /getting-started/configuring-a-service + + - text: Configuring a gRPC Service + url: /getting-started/configuring-a-grpc-service + + - text: Enabling Plugins + url: /getting-started/enabling-plugins + + - text: Adding Consumers + url: /getting-started/adding-consumers + + - text: Configuration reference + url: /configuration + + - text: CLI reference + url: /cli + + - text: Proxy reference + url: /proxy + + - text: Authentication reference + url: /auth + + - text: Load balancing reference + url: /loadbalancing + + - text: Health checks and circuit breakers reference + url: /health-checks-circuit-breakers + + - text: Hybrid Mode + url: /hybrid-mode + + - text: Go Plugins + url: /go + + - text: Clustering reference + url: /clustering + + - text: DB-less & Declarative Configuration Format + url: /db-less-and-declarative-config + + - text: Resource Sizing Guidelines + url: /sizing-guidelines + + - text: Logging reference + url: /logging + + - text: Network & Firewall + url: /network + + - text: Securing the Admin API + url: /secure-admin-api + + - text : Control Kong Community Gateway through systemd + url: /systemd + + - text: Upgrade Guide + url: /upgrading + + - text: Plugin Development Guide + url: /plugin-development + items: + - text: Introduction + url: /plugin-development + + - text: File structure + url: /plugin-development/file-structure + + - text: Implementing custom logic + url: /plugin-development/custom-logic + + - text: Plugin configuration + url: /plugin-development/plugin-configuration + + - text: Accessing the datastore + url: /plugin-development/access-the-datastore + + - text: Storing custom entities + url: /plugin-development/custom-entities + + - text: Caching custom entities + url: /plugin-development/entities-cache + + - text: Extending the Admin API + url: /plugin-development/admin-api + + - text: Writing tests + url: /plugin-development/tests + + - text: (un)Installing your plugin + url: /plugin-development/distribution + + - text: Plugin Development Kit + url: /pdk + items: + + - text: kong.client + url: /pdk/kong.client + + - text: kong.client.tls + url: /pdk/kong.client.tls + + - text: kong.ctx + url: /pdk/kong.ctx + + - text: kong.ip + url: /pdk/kong.ip + + - text: kong.log + url: /pdk/kong.log + + - text: kong.nginx + url: /pdk/kong.nginx + + - text: kong.node + url: /pdk/kong.node + + - text: kong.request + url: /pdk/kong.request + + - text: kong.response + url: /pdk/kong.response + + - text: kong.router + url: /pdk/kong.router + + - text: kong.service + url: /pdk/kong.service + + - text: kong.service.request + url: /pdk/kong.service.request + + - text: kong.service.response + url: /pdk/kong.service.response + + - text: kong.table + url: /pdk/kong.table + +# Generated via autodoc-admin-api +- title: Admin API + url: /admin-api/ + icon: /assets/images/icons/documentation/icn-admin-api-color.svg + items: + - text: DB-less + url: /db-less-admin-api + + - text: Declarative Configuration + url: /db-less-admin-api/#declarative-configuration + + - text: Supported Content Types + url: /admin-api/#supported-content-types + + - text: Information Routes + url: /admin-api/#information-routes + items: + - text: Retrieve Node Information + url: /admin-api/#retrieve-node-information + + - text: List Available Endpoints + url: /admin-api/#list-available-endpoints + + - text: Validate A Configuration against A Schema + url: /admin-api/#validate-a-configuration-against-a-schema + + - text: Retrieve Entity Schema + url: /admin-api/#retrieve-entity-schema + + - text: Retrieve Plugin Schema + url: /admin-api/#retrieve-plugin-schema + + - text: Health Routes + url: /admin-api/#health-routes + items: + - text: Retrieve Node Status + url: /admin-api/#retrieve-node-status + + - text: Tags + url: /admin-api/#tags + items: + - text: List All Tags + url: /admin-api/#list-all-tags + + - text: List Entity Ids by Tag + url: /admin-api/#list-entity-ids-by-tag + + - text: Service Object + url: /admin-api/#service-object + items: + - text: Add Service + url: /admin-api/#add-service + + - text: List Services + url: /admin-api/#list-services + + - text: Retrieve Service + url: /admin-api/#retrieve-service + + - text: Update Service + url: /admin-api/#update-service + + - text: Update Or Create Service + url: /admin-api/#update-or-create-service + + - text: Delete Service + url: /admin-api/#delete-service + + - text: Route Object + url: /admin-api/#route-object + items: + - text: Add Route + url: /admin-api/#add-route + + - text: List Routes + url: /admin-api/#list-routes + + - text: Retrieve Route + url: /admin-api/#retrieve-route + + - text: Update Route + url: /admin-api/#update-route + + - text: Update Or Create Route + url: /admin-api/#update-or-create-route + + - text: Delete Route + url: /admin-api/#delete-route + + - text: Consumer Object + url: /admin-api/#consumer-object + items: + - text: Add Consumer + url: /admin-api/#add-consumer + + - text: List Consumers + url: /admin-api/#list-consumers + + - text: Retrieve Consumer + url: /admin-api/#retrieve-consumer + + - text: Update Consumer + url: /admin-api/#update-consumer + + - text: Update Or Create Consumer + url: /admin-api/#update-or-create-consumer + + - text: Delete Consumer + url: /admin-api/#delete-consumer + + - text: Plugin Object + url: /admin-api/#plugin-object + items: + - text: Add Plugin + url: /admin-api/#add-plugin + + - text: List Plugins + url: /admin-api/#list-plugins + + - text: Retrieve Plugin + url: /admin-api/#retrieve-plugin + + - text: Update Plugin + url: /admin-api/#update-plugin + + - text: Update Or Create Plugin + url: /admin-api/#update-or-create-plugin + + - text: Delete Plugin + url: /admin-api/#delete-plugin + + - text: Retrieve Enabled Plugins + url: /admin-api/#retrieve-enabled-plugins + + - text: Certificate Object + url: /admin-api/#certificate-object + items: + - text: Add Certificate + url: /admin-api/#add-certificate + + - text: List Certificates + url: /admin-api/#list-certificates + + - text: Retrieve Certificate + url: /admin-api/#retrieve-certificate + + - text: Update Certificate + url: /admin-api/#update-certificate + + - text: Update Or Create Certificate + url: /admin-api/#update-or-create-certificate + + - text: Delete Certificate + url: /admin-api/#delete-certificate + + - text: CA Certificate Object + url: /admin-api/#ca-certificate-object + items: + - text: Add CA Certificate + url: /admin-api/#add-ca-certificate + + - text: List CA Certificates + url: /admin-api/#list-ca-certificates + + - text: Retrieve CA Certificate + url: /admin-api/#retrieve-ca-certificate + + - text: Update CA Certificate + url: /admin-api/#update-ca-certificate + + - text: Update Or Create CA Certificate + url: /admin-api/#update-or-create-ca-certificate + + - text: Delete CA Certificate + url: /admin-api/#delete-ca-certificate + + - text: SNI Object + url: /admin-api/#sni-object + items: + - text: Add SNI + url: /admin-api/#add-sni + + - text: List SNIs + url: /admin-api/#list-snis + + - text: Retrieve SNI + url: /admin-api/#retrieve-sni + + - text: Update SNI + url: /admin-api/#update-sni + + - text: Update Or Create SNI + url: /admin-api/#update-or-create-sni + + - text: Delete SNI + url: /admin-api/#delete-sni + + - text: Upstream Object + url: /admin-api/#upstream-object + items: + - text: Add Upstream + url: /admin-api/#add-upstream + + - text: List Upstreams + url: /admin-api/#list-upstreams + + - text: Retrieve Upstream + url: /admin-api/#retrieve-upstream + + - text: Update Upstream + url: /admin-api/#update-upstream + + - text: Update Or Create Upstream + url: /admin-api/#update-or-create-upstream + + - text: Delete Upstream + url: /admin-api/#delete-upstream + + - text: Show Upstream Health for Node + url: /admin-api/#show-upstream-health-for-node + + - text: Target Object + url: /admin-api/#target-object + items: + - text: Add Target + url: /admin-api/#add-target + + - text: List Targets + url: /admin-api/#list-targets + + - text: Delete Target + url: /admin-api/#delete-target + + - text: Set Target Address As Healthy + url: /admin-api/#set-target-address-as-healthy + + - text: Set Target Address As Unhealthy + url: /admin-api/#set-target-address-as-unhealthy + + - text: Set Target As Healthy + url: /admin-api/#set-target-as-healthy + + - text: Set Target As Unhealthy + url: /admin-api/#set-target-as-unhealthy + + - text: List All Targets + url: /admin-api/#list-all-targets + +- title: Kong for Kubernetes + icon: /assets/images/icons/documentation/icn-kubernetes-color.svg + url: /kong-for-kubernetes/ + items: + - text: Install Kong for Kubernetes + url: /kong-for-kubernetes/install + + - text: Using Kong for Kubernetes + url: /kong-for-kubernetes/using-kong-for-kubernetes + + - text: Changelog + url: /kong-for-kubernetes/changelog + +- title: decK + icon: /assets/images/icons/documentation/icn-dev-portal-color.svg + items: + - text: Introduction + items: + - text: Overview + url: /../../deck/overview + - text: Terminology + url: /../../deck/terminology + - text: Architecture + url: /../../deck/design-architecture + - text: Compatibility Promise + url: /../../deck/compatibility-promise + - text: Installation + url: /../../deck/installation + - text: Guides + items: + - text: Getting Started with decK + url: /../../deck/guides/getting-started + - text: Backup and Restore + url: /../../deck/guides/backup-restore + - text: Configuration as Code and GitOps + url: /../../deck/guides/ci-driven-configuration + - text: Distributed Configuration + url: /../../deck/guides/distributed-configuration + - text: Best Practices + url: /../../deck/guides/best-practices + - text: Using decK with Kong Enterprise + url: /../../deck/guides/kong-enterprise + - text: Using Multiple Files to Store Configuration + url: /../../deck/guides/multi-file-state + - text: De-duplicate Plugin Configuration + url: /../../deck/guides/deduplicate-plugin-configuration + - text: decK CLI Reference + url: /../../deck/commands + - text: FAQ + url: /../../deck/faqs + - text: Changelog + url: https://github.com/kong/deck/blob/main/CHANGELOG.md + absolute_url: true diff --git a/app/_data/docs_nav_ee_1.3-x.yml b/app/_data/docs_nav_ee_1.3-x.yml index 42b72ac23dfa..4eaa00e4fa9d 100644 --- a/app/_data/docs_nav_ee_1.3-x.yml +++ b/app/_data/docs_nav_ee_1.3-x.yml @@ -276,6 +276,8 @@ url: /developer-portal/legacy-migration - text: Structure and File Types url: /developer-portal/structure-and-file-types + - text: Using the Portal Files API + url: /developer-portal/files-api - text: Working with Templates url: /developer-portal/working-with-templates - text: Using the Editor diff --git a/app/_data/docs_nav_ee_1.5.x.yml b/app/_data/docs_nav_ee_1.5.x.yml index 5838d5a863b1..0d0a1bc49f2b 100644 --- a/app/_data/docs_nav_ee_1.5.x.yml +++ b/app/_data/docs_nav_ee_1.5.x.yml @@ -321,6 +321,8 @@ url: /developer-portal/legacy-migration - text: Structure and File Types url: /developer-portal/structure-and-file-types + - text: Using the Portal Files API + url: /developer-portal/files-api - text: Working with Templates url: /developer-portal/working-with-templates - text: Using the Editor diff --git a/app/_data/docs_nav_ee_2.1.x.yml b/app/_data/docs_nav_ee_2.1.x.yml index d19aed47a085..dc015d35fde1 100644 --- a/app/_data/docs_nav_ee_2.1.x.yml +++ b/app/_data/docs_nav_ee_2.1.x.yml @@ -348,7 +348,7 @@ - text: Add a Workspace url: /kong-manager/administration/workspaces/add-workspace - text: RBAC - - items: + items: - text: RBAC in Kong Manager url: /kong-manager/administration/rbac - text: Create a New Role @@ -358,7 +358,7 @@ - text: Add a Role and Permissions url: /kong-manager/administration/rbac/add-role - text: Admins - - items: + items: - text: Invite an Admin url: /kong-manager/administration/admins/invite - text: Add an Admin @@ -385,6 +385,8 @@ url: /developer-portal/legacy-migration - text: Structure and File Types url: /developer-portal/structure-and-file-types + - text: Using the Portal Files API + url: /developer-portal/files-api - text: Working with Templates url: /developer-portal/working-with-templates - text: Using the Editor @@ -424,6 +426,8 @@ url: /developer-portal/administration/application-registration/enable-application-registration - text: Set up Okta and Kong for external OAuth url: /developer-portal/administration/application-registration/okta-config + - text: Set Up Azure AD and Kong for External Authentication + url: /developer-portal/administration/application-registration/azure-oidc-config - text: Manage Applications url: /developer-portal/administration/application-registration/managing-applications - text: Customization @@ -474,7 +478,8 @@ - text: Deployment Options url: /kong-for-kubernetes/deployment-options - text: Changelog - url: /kong-for-kubernetes/changelog + url: https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md + absolute_url: true - title: Kong Vitals icon: /assets/images/icons/documentation/icn-vitals.svg diff --git a/app/_data/extensions/kong-inc/correlation-id/versions.yml b/app/_data/extensions/kong-inc/correlation-id/versions.yml index f56356207baf..8b8c4b784126 100644 --- a/app/_data/extensions/kong-inc/correlation-id/versions.yml +++ b/app/_data/extensions/kong-inc/correlation-id/versions.yml @@ -1,2 +1,3 @@ -- release: 1.0-x -- release: 0.1-x +- release: 2.0.x +- release: 1.0.x +- release: 0.1.x diff --git a/app/_data/extensions/kong-inc/grpc-gateway/versions.yml b/app/_data/extensions/kong-inc/grpc-gateway/versions.yml index 24a6268a6996..6e09fadd023d 100644 --- a/app/_data/extensions/kong-inc/grpc-gateway/versions.yml +++ b/app/_data/extensions/kong-inc/grpc-gateway/versions.yml @@ -1 +1 @@ -- release: 0.1.0 +- release: 0.1.x diff --git a/app/_data/extensions/kong-inc/grpc-web/versions.yml b/app/_data/extensions/kong-inc/grpc-web/versions.yml index dc3ae81aef3e..8f68dd8fa36b 100644 --- a/app/_data/extensions/kong-inc/grpc-web/versions.yml +++ b/app/_data/extensions/kong-inc/grpc-web/versions.yml @@ -1 +1,2 @@ -- release: 0.1.1 +- release: 0.2.x +- release: 0.1.x diff --git a/app/_data/extensions/kong-inc/ip-restriction/versions.yml b/app/_data/extensions/kong-inc/ip-restriction/versions.yml index f56356207baf..7993cf5a203c 100644 --- a/app/_data/extensions/kong-inc/ip-restriction/versions.yml +++ b/app/_data/extensions/kong-inc/ip-restriction/versions.yml @@ -1,2 +1,3 @@ +- release: 2.0.x - release: 1.0-x - release: 0.1-x diff --git a/app/_data/kong_versions.yml b/app/_data/kong_versions.yml index 3b48b198cf84..9f856c551b27 100644 --- a/app/_data/kong_versions.yml +++ b/app/_data/kong_versions.yml @@ -287,7 +287,7 @@ lua_doc: true - release: "1.5.x" - version: "1.5" + version: "1.5.0.6" edition: "enterprise" luarocks_version: "0.34.x" dependencies: @@ -299,7 +299,7 @@ lua_doc: true - release: "2.1.x" - version: "2.1.3.0" + version: "2.1.4.0" edition: "enterprise" luarocks_version: "0.34.x" dependencies: @@ -337,9 +337,9 @@ openresty: "1.15.8.3" - release: "2.1.x" - version: "2.1.3" + version: "2.1.4" edition: "community" - luarocks_version: "2.1.3-0" + luarocks_version: "2.1.4-0" dependencies: luajit: "2.1.0-beta3" luarocks: "3.3.1" @@ -349,6 +349,20 @@ openssl: "1.1.1g" libyaml: "0.2.5" pcre: "8.44" +- + release: "2.2.x" + version: "2.2.0" + edition: "community" + luarocks_version: "2.2.0-0" + dependencies: + luajit: "2.1.0-beta3" + luarocks: "3.3.1" + cassandra: "3.x.x" + postgres: "9.5+" + openresty: "1.17.8.2" + openssl: "1.1.1h" + libyaml: "0.2.5" + pcre: "8.44" - release: "CE-2.0.x_KE-1.5.x" version: "CE-2.0.x/KE-1.5.x" @@ -358,8 +372,9 @@ version: "2.1" edition: "getting-started-guide" - + version: "1.2.1" edition: "deck" - release: "1.0.x" - version: "1.0.1" + version: "1.0.4" edition: "mesh" diff --git a/app/_hub/kong-inc/acl/index.md b/app/_hub/kong-inc/acl/index.md index f4aba4464fa5..706027014289 100644 --- a/app/_hub/kong-inc/acl/index.md +++ b/app/_hub/kong-inc/acl/index.md @@ -3,9 +3,15 @@ name: ACL publisher: Kong Inc. version: 1.0.0 -desc: Control which consumers can access Services +desc: Control which Consumers can access Services description: | - Restrict access to a Service or a Route by adding consumers to allowed or denied lists using arbitrary ACL group names. This plugin requires an [authentication plugin](/about/faq/#how-can-i-add-authentication-to-a-microservice-api) to have been already enabled on the Service or Route. + Restrict access to a Service or a Route by adding Consumers to allowed or + denied lists using arbitrary ACL group names. This plugin requires an + [authentication plugin](/hub/#authentication) (such as + [Basic Authentication](/hub/kong-inc/basic-auth/), + [Key Authentication](/hub/kong-inc/key-auth/), [OAuth 2.0](/hub/kong-inc/oauth2/), + and [OpenID Connect](/hub/kong-inc/openid-connect/)) + to have been already enabled on the Service or Route.
Note: The functionality of this plugin as bundled @@ -40,10 +46,6 @@ kong_version_compatibility: - 0.7.x - 0.6.x - 0.5.x -# incompatible: -# - 0.4.x -# - 0.3.x -# - 0.2.x enterprise_edition: compatible: - 2.1.x @@ -55,7 +57,6 @@ kong_version_compatibility: - 0.33-x - 0.32-x - 0.31-x -# incompatible: params: name: acl @@ -67,7 +68,7 @@ params: dbless_explanation: | Consumers and ACLs can be created with declarative configuration. - Admin API endpoints which do POST, PUT, PATCH or DELETE on ACLs will not work on DB-less mode. + Admin API endpoints that do POST, PUT, PATCH or DELETE on ACLs will not work on DB-less mode. config: - name: allow required: semi @@ -85,33 +86,38 @@ params: default: false value_in_examples: true description: | - Flag which if enabled (`true`), prevents the `X-Consumer-Groups` header to be sent in the request to the upstream service. + Flag that if enabled (`true`), prevents the `X-Consumer-Groups` header to be sent in the request to the Upstream service. extra: | Note that the `allow` and `deny` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure an ACL with both `allow` and `deny` configurations. An ACL with an `allow` provides a positive security model, in which the configured groups are allowed access to the resources, and all others are inherently rejected. By contrast, a `deny` configuration provides a negative security model, in which certain groups are explicitly denied access to the resource (and all others are inherently allowed). --- ### Usage -In order to use this plugin, you need to properly have configured your Service or Route with an [authentication plugin][faq-authentication] so that the plugin can identify who is the client [Consumer][consumer-object] making the request. +Before you use the ACL plugin, you need to have properly configured your Service or +Route with an [authentication plugin](/hub/#authentication) +so that the plugin can identify the client Consumer making the request. #### Associating Consumers -{% tabs %} -{% tab With a database %} -Once you have added an authentication plugin to a Service or a Route and you have created your [Consumers][consumer-object], you can now associate a group to a [Consumer][consumer-object] using the following request: +{% navtabs %} +{% navtab With a database %} + +After you have added an authentication plugin to a Service or a Route, and you have +created your [Consumers](/latest/admin-api/#consumer-object), you can now +associate a group to a Consumer using the following request: ```bash $ curl -X POST http://kong:8001/consumers/{consumer}/acls \ --data "group=group1" ``` -`consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. +`consumer`: The `id` or `username` property of the Consumer entity to associate the credentials to. form parameter | default| description --- | --- | --- `group` | | The arbitrary group name to associate to the consumer. - -{% tab Without a database %} +{% endnavtab %} +{% navtab Without a database %} You can create ACL objects via the `acls:` entry in the declarative configuration file: ``` yaml @@ -120,17 +126,22 @@ acls: group: group1 ``` -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. -* `group`: The arbitrary group name to associate to the consumer. -{% endtabs %} +* `consumer`: The `id` or `username` property of the Consumer entity to associate the credentials to. +* `group`: The arbitrary group name to associate to the Consumer. +{% endnavtab %} +{% endnavtabs %} -You can have more than one group associated to a consumer. +You can have more than one group associated to a Consumer. #### Upstream Headers -When a consumer has been validated, the plugin will append a `X-Consumer-Groups` header to the request before proxying it to the upstream service, so that you can identify the groups associated with the consumer. The value of the header is a comma separated list of groups that belong to the consumer, like `admin, pro_user`. +When a consumer has been validated, the plugin appends a `X-Consumer-Groups` +header to the request before proxying it to the Upstream service, so that you can +identify the groups associated with the Consumer. The value of the header is a +comma-separated list of groups that belong to the Consumer, like `admin, pro_user`. -This header will not be injected in the request to the upstream service if the `hide_groups_header` config flag is set to `true`. +This header will not be injected in the request to the Upstream service if +the `hide_groups_header` config flag is set to `true`. #### Paginate through the ACLs @@ -169,7 +180,7 @@ $ curl -X GET http://kong:8001/acls } ``` -You can filter the list by consumer by using this other path: +You can filter the list by Consumer by using this other path: ```bash $ curl -X GET http://kong:8001/consumers/{username or id}/acls @@ -187,7 +198,7 @@ $ curl -X GET http://kong:8001/consumers/{username or id}/acls } ``` -`username or id`: The username or id of the consumer whose ACLs need to be listed +`username or id`: The username or id of the Consumer whose ACLs need to be listed #### Retrieve the Consumer associated with an ACL @@ -195,7 +206,7 @@ $ curl -X GET http://kong:8001/consumers/{username or id}/acls Note: This endpoint was introduced in Kong 0.11.2.
-It is possible to retrieve a [Consumer][consumer-object] associated with an ACL +Retrieve a Consumer associated with an ACL using the following request: ```bash @@ -209,9 +220,8 @@ curl -X GET http://kong:8001/acls/{id}/consumer ``` `id`: The `id` property of the ACL for which to get the associated -[Consumer][consumer-object]. +Consumer. -[cidr]: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation -[configuration]: /latest/configuration -[consumer-object]: /latest/admin-api/#consumer-object -[faq-authentication]: /about/faq/#how-can-i-add-authentication-to-a-microservice-api +#### See also +- [cidr](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) +- [configuration](/latest/configuration) diff --git a/app/_hub/kong-inc/acme/0.2.2.md b/app/_hub/kong-inc/acme/0.2.2.md index 0b1b9ea240cd..f6078a2cdb1f 100644 --- a/app/_hub/kong-inc/acme/0.2.2.md +++ b/app/_hub/kong-inc/acme/0.2.2.md @@ -122,7 +122,7 @@ is mapped to a Route in Kong. You can check this by sending If not, add a Route and a dummy Service to catch this route. ```bash # add a dummy service if needed -$ curl http://localhost:8001/service \ +$ curl http://localhost:8001/services \ -d name=acme-dummy \ -d url=http://127.0.0.1:65535 diff --git a/app/_hub/kong-inc/acme/0.2.7.md b/app/_hub/kong-inc/acme/0.2.7.md new file mode 100644 index 000000000000..7631e669ce4a --- /dev/null +++ b/app/_hub/kong-inc/acme/0.2.7.md @@ -0,0 +1,275 @@ +--- +name: ACME +publisher: Kong Inc. +version: 0.2.7 + +source_url: https://github.com/Kong/kong-plugin-acme + +desc: Let's Encrypt and ACMEv2 integration with Kong +description: | + This plugin allows Kong to apply certificates from Let's Encrypt or any other ACMEv2 service and serve dynamically. Renewal is handled with a configurable threshold time. + +type: plugin +categories: + - security + +kong_version_compatibility: + community_edition: + compatible: + - 2.1.x + - 2.0.x + enterprise_edition: + compatible: + - 2.1.x + +params: + name: acme + api_id: false + service_id: false + route_id: false + consumer_id: false + protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] + dbless_compatible: yes + config: + - name: account_email + required: yes + default: + value_in_examples: example@example.com + description: | + The account identifier, can be reused in different plugin instance. + - name: api_uri + required: false + default: "`https://acme-v02.api.letsencrypt.org`" + description: | + The ACMEv2 API endpoint to use. Users can specify the [Let's Encrypt staging environment](https://letsencrypt.org/docs/staging-environment/) (`https://acme-staging-v02.api.letsencrypt.org/directory`) for testing. Note that Kong doesn't automatically delete staging certificates: if you use same domain to test and use in production, you will need to delete those certificates manually after testing. + - name: cert_type + required: false + default: "`rsa`" + description: | + The certificate type to create. The possible values are `"rsa"` for RSA certificate or `"ecc"` for EC certificate. + - name: domains + required: false + default: "`[]`" + description: | + The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name or Subject Alternative Name to create certifcates; each domain will have its own certificate. + - name: renew_threshold_days + required: false + default: "`14`" + description: | + Days before expire to renew the certificate. + - name: storage + required: false + default: "`shm`" + description: | + The backend storage type to use. The possible values are `"kong"`, `"shm"`, `"redis"`, `"consul"`, or `"vault"`. In DB-less mode, `"kong"` storage is unavailable. Note that `"shm"` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `"kong"`, `"redis"`, `"consul"`, or `"vault"` in production. + - name: storage_config + required: false + default: + description: | + Storage configs for each backend storage. See below for its default value. + - name: tos_accepted + required: false + default: "`false`" + description: | + If you are using Let's Encrypt, you must set this to true to agree the [Terms of Service](https://letsencrypt.org/repository/). + extra: | + `config.storage_config` is a table for all posisble storage types, by default it is: + ```json + "storage_config": { + "kong": {}, + "shm": { + "shm_name": "kong" + }, + "redis": { + "auth": null, + "port": 6379, + "database": 0, + "host": "127.0.0.1" + }, + "consul": { + "host": "127.0.0.1", + "port": 8500, + "token": null, + "kv_path": "acme", + "timeout": 2000, + "https": false + }, + "vault": { + "host": "127.0.0.1", + "port": 8200, + "token": null, + "kv_path": "acme", + "timeout": 2000, + "https": false, + "tls_verify": true, + "tls_server_name": null + }, + } + ``` + + To configure storage type other than `kong`, please refer to [lua-resty-acme](https://github.com/fffonion/lua-resty-acme#storage-adapters). + +--- + +### Using the Plugin + +#### Configure Kong + +- Kong needs to listen 80 port or proxied by a load balancer that listens for 80 port. +- `lua_ssl_trusted_certificate` needs to be set in `kong.conf` to ensure the plugin can properly +verify Let's Encrypt API. The CA-bundle file is usually `/etc/ssl/certs/ca-certificates.crt` for +Ubuntu/Debian and `/etc/ssl/certs/ca-bundle.crt` for CentOS/Fedora/RHEL. + +#### Configure Plugin + +Here's a sample declarative configuration with `redis` as storage: + +```yaml +_format_version: "1.1" +# this section is not necessary if there's already a route that matches +# /.well-known/acme-challenge path with http protocol +services: + - name: acme-dummy + url: http://127.0.0.1:65535 + routes: + - name: acme-dummy + protocols: + - http + paths: + - /.well-known/acme-challenge +plugins: + - name: acme + config: + account_email: example@myexample.com + domains: + - "*.example.com" + - "example.com" + tos_accepted: true + storage: redis + storage_config: + redis: + host: redis.service + port: 6379 +``` + +#### Enable the Plugin + +For each the domain that needs a certificate, make sure `DOMAIN/.well-known/acme-challenge` +is mapped to a Route in Kong. You can check this by sending +`curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"` and getting the response `Not found`. +You can also [use the Admin API](#create-certificates) to verify the setup. +If not, add a Route and a dummy Service to catch this route. +```bash +# add a dummy service if needed +$ curl http://localhost:8001/services \ + -d name=acme-dummy \ + -d url=http://127.0.0.1:65535 + +# add a dummy route if needed +$ curl http://localhost:8001/routes \ + -d name=acme-dummy \ + -d paths[]=/.well-known/acme-challenge \ + -d service.name=acme-dummy + +# add the plugin +$ curl http://localhost:8001/plugins \ + -d name=acme \ + -d config.account_email=yourname@yourdomain.com \ + -d config.tos_accepted=true \ + -d config.domains[]=my.secret.domains.com +``` + +Note by setting `tos_accepted` to *true* implies that you have read and accepted +[terms of service](https://letsencrypt.org/repository/). + +**This plugin can only be configured as a global plugin.** The plugin terminates +`/.well-known/acme-challenge/` path for matching domains. To create certificates +and terminate challenges only for certain domains, please refer to the +[Parameters](#parameters) section. + +#### Trigger creation of certificate + +Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com. + +```bash +# Trigger asynchronous creation from proxy requests +# The following request returns immediately with Kong's default certificate +# Wait up to 1 minute for the background process to finish +$ curl https://mydomain.com -k + +# OR create from Admin API synchronously +# User can also use this endpoint to force "renew" a certificate +$ curl http://localhost:8001/acme -d host=mydomain.com + +# Furthermore, it's possible to run a sanity test on your Kong setup +# before creating any certificate +$ curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true + +$ curl https://mydomain.com +# Now gives you a valid Let's Encrypt certicate +``` + +### Local testing and development + +#### Run ngrok + +[ngrok](https://ngrok.com) exposes a local URL to the internet. [Download ngrok](https://ngrok.com/download) and install. + +*`ngrok` is only needed for local testing or development, it's **not** a requirement for the plugin itself.* + +Run ngrok with + +```bash +$ ./ngrok http localhost:8000 +# Shows something like +# ... +# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000 +# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000 +# ... +# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output +$ export NGROK_HOST=e2e034a5.ngrok.io +``` + +Leave the process running. + +#### Configure Route and Service + +```bash +$ curl http://localhost:8001/services -d name=acme-test -d url=http://mockbin.org +$ curl http://localhost:8001/routes -d service.name=acme-test -d hosts=$NGROK_HOST +``` + +#### Enable Plugin + +```bash +$ curl localhost:8001/plugins -d name=acme \ + -d config.account_email=test@test.com \ + -d config.tos_accepted=true \ + -d config.domains[]=$NGROK_HOST +``` + +#### Trigger creation of certificate + +```bash +$ curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk +# Wait for several seconds +``` + +#### Check new certificate + +```bash +$ echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout +``` + +### Notes + +- In database mode, the plugin creates SNI and Certificate entity in Kong to +serve certificate. If SNI or Certificate for current request is already set +in database, they will be overwritten. +- In DB-less mode, the plugin takes over certificate handling, if the SNI or +Certificate entity is already defined in Kong, they will be overrided from +response. +- The plugin only supports http-01 challenge, meaning user will need a public +IP and setup resolvable DNS. Kong also needs to accept proxy traffic from port `80`. +Also, note that wildcard or star certificate is not supported, each domain will have its +own certificate. diff --git a/app/_hub/kong-inc/acme/index.md b/app/_hub/kong-inc/acme/index.md index cdbe4a6c56a7..dea652606605 100644 --- a/app/_hub/kong-inc/acme/index.md +++ b/app/_hub/kong-inc/acme/index.md @@ -1,7 +1,7 @@ --- name: ACME publisher: Kong Inc. -version: 0.2.7 +version: 0.2.11 source_url: https://github.com/Kong/kong-plugin-acme @@ -16,6 +16,7 @@ categories: kong_version_compatibility: community_edition: compatible: + - 2.2.x - 2.1.x - 2.0.x enterprise_edition: @@ -52,6 +53,11 @@ params: default: "`[]`" description: | The list of domains to create certificate for. To match subdomains under `example.com`, use `*.example.com`. Regex pattern is not supported. Note this config is only used to match domains, not to specify the Common Name or Subject Alternative Name to create certifcates; each domain will have its own certificate. + - name: fail_backoff_minutes + required: false + default: 5 + description: | + Minutes to wait for each domain that fails to create a certificate. This applies to both new certificate and renewal. - name: renew_threshold_days required: false default: "`14`" @@ -161,7 +167,7 @@ You can also [use the Admin API](#create-certificates) to verify the setup. If not, add a Route and a dummy Service to catch this route. ```bash # add a dummy service if needed -$ curl http://localhost:8001/service \ +$ curl http://localhost:8001/services \ -d name=acme-dummy \ -d url=http://127.0.0.1:65535 diff --git a/app/_hub/kong-inc/aws-lambda/0.1-x.md b/app/_hub/kong-inc/aws-lambda/0.1-x.md index 0fcc56651bc1..3cb9bc037362 100644 --- a/app/_hub/kong-inc/aws-lambda/0.1-x.md +++ b/app/_hub/kong-inc/aws-lambda/0.1-x.md @@ -43,6 +43,7 @@ params: service_id: true route_id: true consumer_id: true + protocols: ["http", "https"] config: - name: aws_key required: true diff --git a/app/_hub/kong-inc/aws-lambda/1.0-x.md b/app/_hub/kong-inc/aws-lambda/1.0-x.md index 910f011ae00a..917fd9a53e58 100644 --- a/app/_hub/kong-inc/aws-lambda/1.0-x.md +++ b/app/_hub/kong-inc/aws-lambda/1.0-x.md @@ -1,7 +1,7 @@ --- name: AWS Lambda publisher: Kong Inc. -version: 1.0.x +version: 1.0-x desc: Invoke and manage AWS Lambda functions from Kong description: | diff --git a/app/_hub/kong-inc/aws-lambda/3.0-x.md b/app/_hub/kong-inc/aws-lambda/3.0.x.md similarity index 99% rename from app/_hub/kong-inc/aws-lambda/3.0-x.md rename to app/_hub/kong-inc/aws-lambda/3.0.x.md index 70694610de9c..dc07abab14f0 100644 --- a/app/_hub/kong-inc/aws-lambda/3.0-x.md +++ b/app/_hub/kong-inc/aws-lambda/3.0.x.md @@ -53,7 +53,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https"] dbless_compatible: yes config: - name: aws_key diff --git a/app/_hub/kong-inc/aws-lambda/index.md b/app/_hub/kong-inc/aws-lambda/index.md index 7e1884d82668..97ef343ccd1d 100644 --- a/app/_hub/kong-inc/aws-lambda/index.md +++ b/app/_hub/kong-inc/aws-lambda/index.md @@ -55,7 +55,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https"] dbless_compatible: yes config: - name: aws_key diff --git a/app/_hub/kong-inc/azure-functions/0.1-x.md b/app/_hub/kong-inc/azure-functions/0.1-x.md index 680980a54142..50a20ee17244 100644 --- a/app/_hub/kong-inc/azure-functions/0.1-x.md +++ b/app/_hub/kong-inc/azure-functions/0.1-x.md @@ -33,7 +33,7 @@ params: - name: functionname required: true default: - value_in_exaples: AZURE_FUNCTIONNAME + value_in_examples: AZURE_FUNCTIONNAME description: Name of the Azure function to invoke. - name: appname required: true @@ -54,12 +54,12 @@ params: required: false default: value_in_examples: AZURE_APIKEY - description: The apikey to access the Azure resources. If provided it will be injected as the `x-functions-key` header. + description: The apikey to access the Azure resources. If provided, it will be injected as the `x-functions-key` header. - name: clientid required: false default: value_in_examples: - description: The clientid to access the Azure resources. If provided it will be injected as the `x-functions-clientid` header. + description: The clientid to access the Azure resources. If provided, it will be injected as the `x-functions-clientid` header. - name: https_verify required: false default: false @@ -82,7 +82,7 @@ params: description: Time in milliseconds for which an idle connection to the Azure Functions server will live before being closed. extra: | - Note: If `config.https_verify` is set as `true` then the server certificate + Note: If `config.https_verify` is set as `true`, then the server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive in your Kong configuration. diff --git a/app/_hub/kong-inc/azure-functions/index.md b/app/_hub/kong-inc/azure-functions/index.md index 281d7ae50d96..f1e6d0a764a4 100644 --- a/app/_hub/kong-inc/azure-functions/index.md +++ b/app/_hub/kong-inc/azure-functions/index.md @@ -68,12 +68,12 @@ params: required: false default: value_in_examples: AZURE_APIKEY - description: The apikey to access the Azure resources. If provided it will be injected as the `x-functions-key` header. + description: The apikey to access the Azure resources. If provided, it will be injected as the `x-functions-key` header. - name: clientid required: false default: value_in_examples: - description: The clientid to access the Azure resources. If provided it will be injected as the `x-functions-clientid` header. + description: The clientid to access the Azure resources. If provided, it will be injected as the `x-functions-clientid` header. - name: https_verify required: false default: false @@ -96,7 +96,7 @@ params: description: Time in milliseconds for which an idle connection to the Azure Functions server will live before being closed. extra: | - Note: If `config.https_verify` is set as `true` then the server certificate + Note: If `config.https_verify` is set as `true`, then the server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive in your Kong configuration. @@ -170,7 +170,7 @@ To demonstrate the plugin, set up the [Azure Functions "hello world" function](h "Hello Kong!" ``` -In this example we're only passing a query parameter `name` to the Azure +In this example, we're only passing a query parameter `name` to the Azure Function. Besides query parameters, also the HTTP method, path parameters, headers, and body will be passed to the Azure Function if provided. diff --git a/app/_hub/kong-inc/correlation-id/0.1-x.md b/app/_hub/kong-inc/correlation-id/0.1.x.md similarity index 98% rename from app/_hub/kong-inc/correlation-id/0.1-x.md rename to app/_hub/kong-inc/correlation-id/0.1.x.md index 38f9389a6b6d..294d71fd6e4c 100644 --- a/app/_hub/kong-inc/correlation-id/0.1-x.md +++ b/app/_hub/kong-inc/correlation-id/0.1.x.md @@ -62,7 +62,7 @@ When enabled, this plugin will add a new header to all of the requests processed This header is always added to calls to your upstream services, and optionally echoed back to your clients according to the `config.echo_downstream` setting. -If a header bearing the same name is already present in the client request, it is honored and this plugin will **not** temper with it. +If a header bearing the same name is already present in the client request, it is honored and this plugin will **not** tamper with it. ## Generators diff --git a/app/_hub/kong-inc/correlation-id/1.0.x.md b/app/_hub/kong-inc/correlation-id/1.0.x.md new file mode 100644 index 000000000000..c4fa0e0519e1 --- /dev/null +++ b/app/_hub/kong-inc/correlation-id/1.0.x.md @@ -0,0 +1,127 @@ +--- +name: Correlation ID +publisher: Kong Inc. +version: 1.0.x + +desc: Correlate requests and responses using a unique ID +description: | + Correlate requests and responses using a unique ID transmitted over an HTTP header. + +type: plugin +categories: + - transformations + +kong_version_compatibility: + community_edition: + compatible: + - 2.1.x + - 2.0.x + - 1.5.x + - 1.4.x + - 1.3.x + - 1.2.x + - 1.1.x + - 1.0.x + - 0.14.x + - 0.13.x + - 0.12.x + - 0.11.x + - 0.10.x + - 0.9.x + - 0.8.x + enterprise_edition: + compatible: + - 2.1.x + - 1.5.x + - 1.3-x + - 0.36-x + - 0.35-x + - 0.34-x + - 0.33-x + - 0.32-x + - 0.31-x + +params: + name: correlation-id + service_id: true + route_id: true + consumer_id: true + protocols: ["http", "https"] + dbless_compatible: yes + config: + - name: header_name + required: false + default: "`Kong-Request-ID`" + value_in_examples: Kong-Request-ID + description: | + The HTTP header name to use for the correlation ID. + - name: generator + required: false + default: "`uuid#counter`" + value_in_examples: uuid#counter + description: | + The generator to use for the correlation ID. Accepted values are `uuid`, `uuid#counter` and `tracker` See [Generators](#generators). + - name: echo_downstream + required: false + default: "`false`" + value_in_examples: false + description: | + Whether to echo the header back to downstream (the client). + +--- + +## How it works + +When enabled, this plugin will add a new header to all of the requests processed by Kong. This header bears the name configured in `config.header_name`, and a unique value generated according to `config.generator`. + +This header is always added to calls to your upstream services, and optionally echoed back to your clients according to the `config.echo_downstream` setting. + +If a header bearing the same name is already present in the client request, it is honored and this plugin will **not** tamper with it. + +## Generators + +### uuid + +Format: +``` +xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +``` + +Using this format, a UUID is generated in its hexadecimal form for each request. + +### uuid#counter + +Format: +``` +xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx#counter +``` + +In this format, a single UUID is generated on a per-worker basis, and further requests simply append a counter to the UUID after a `#` character. The `counter` value starts at `0` for each worker, and gets incremented independently of the others. + +This format provides a better performance, but might be harder to store or process for analyzing (due to its format and low cardinality). + +### tracker + +Format: +``` +ip-port-pid-connection-connection_requests-timestamp +``` + +In this format, the correlation id contains more practical implications for each request. + +The following is a detailed description of the field + +form parameter | description +--- | --- +`ip` | an address of the server which accepted a request +`port` | port of the server which accepted a request +`pid` | pid of the nginx worker process +`connection` | connection serial number +`connection_requests` | current number of requests made through a connection +`timestamp` | a floating-point number for the elapsed time in seconds (including milliseconds as the decimal part) from the epoch for the current time stamp from the nginx cached time + +## FAQ + +### Can I see my correlation ids in my Kong logs? + +The correlation id will not show up in the Nginx access or error logs. As such, we suggest you use this plugin alongside one of the Logging plugins, or store this id on your backend-side. diff --git a/app/_hub/kong-inc/correlation-id/index.md b/app/_hub/kong-inc/correlation-id/index.md index 67213fb1e966..1633a382cea1 100644 --- a/app/_hub/kong-inc/correlation-id/index.md +++ b/app/_hub/kong-inc/correlation-id/index.md @@ -1,7 +1,7 @@ --- name: Correlation ID publisher: Kong Inc. -version: 1.0.0 +version: 2.0.x desc: Correlate requests and responses using a unique ID description: | @@ -14,6 +14,7 @@ categories: kong_version_compatibility: community_edition: compatible: + - 2.2.x - 2.1.x - 2.0.x - 1.5.x diff --git a/app/_hub/kong-inc/cors/index.md b/app/_hub/kong-inc/cors/index.md index aba096a8b46a..696f936dbc44 100644 --- a/app/_hub/kong-inc/cors/index.md +++ b/app/_hub/kong-inc/cors/index.md @@ -5,7 +5,8 @@ version: 1.0.0 desc: Allow developers to make requests from the browser description: | - Easily add __Cross-origin resource sharing *(CORS)*__ to a Service, a Route by enabling this plugin. + Easily add __Cross-origin resource sharing *(CORS)*__ to a Service and a Route + by enabling this plugin.
Note: The functionality of this plugin as bundled @@ -68,19 +69,19 @@ params: default: value_in_examples: ["http://mockbin.com"] description: | - List of allowed domains for the `Access-Control-Allow-Origin` header. If you wish to allow all origins, add `*` as a single value to this configuration field. The accepted values can either be flat strings or PCRE regexes. **NOTE**: Prior to Kong 0.10.x, this parameter was `config.origin` (note the change in trailing `s`), and only accepted a single value, or the `*` special value. + List of allowed domains for the `Access-Control-Allow-Origin` header. If you want to allow all origins, add `*` as a single value to this configuration field. The accepted values can either be flat strings or PCRE regexes. **NOTE**: Prior to Kong 0.10.x, this parameter was `config.origin` (note the change in trailing `s`), and only accepted a single value, or the `*` special value. - name: methods required: false default: "`GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS, TRACE, CONNECT`" value_in_examples: [ "GET", "POST" ] description: - Value for the `Access-Control-Allow-Methods` header + Value for the `Access-Control-Allow-Methods` header. - name: headers required: false default: "Value of the `Access-Control-Request-Headers` request header" value_in_examples: [ "Accept", "Accept-Version", "Content-Length", "Content-MD5", "Content-Type", "Date", "X-Auth-Token" ] description: | - Value for the `Access-Control-Allow-Headers` header + Value for the `Access-Control-Allow-Headers` header. - name: exposed_headers required: false default: @@ -98,11 +99,11 @@ params: default: value_in_examples: 3600 description: | - Indicated how long the results of the preflight request can be cached, in `seconds`. + Indicates how long the results of the preflight request can be cached, in `seconds`. - name: preflight_continue required: false default: "`false`" - description: A boolean value that instructs the plugin to proxy the `OPTIONS` preflight request to the upstream service. + description: A boolean value that instructs the plugin to proxy the `OPTIONS` preflight request to the Upstream service. --- @@ -116,12 +117,9 @@ If the client is a browser, there is a known issue with this plugin caused by a limitation of the CORS specification that doesn't allow to specify a custom `Host` header in a preflight `OPTIONS` request. -Because of this limitation, this plugin will only work for Routes that have been -configured with a `paths` setting, and it will not work for Routes that +Because of this limitation, this plugin only works for Routes that have been +configured with a `paths` setting. The CORS plugin does not work for Routes that are being resolved using a custom DNS (the `hosts` property). -To learn how to configure `paths` for a Route, please read the [Proxy -Reference][proxy-reference]. - -[configuration]: /latest/configuration -[proxy-reference]: /0.12.x/proxy#request-uri +To learn how to configure `paths` for a Route, read the [Proxy +Reference](/latest/proxy). diff --git a/app/_hub/kong-inc/datadog/index.md b/app/_hub/kong-inc/datadog/index.md index 70ed12aff964..1e3b72a2c135 100644 --- a/app/_hub/kong-inc/datadog/index.md +++ b/app/_hub/kong-inc/datadog/index.md @@ -55,7 +55,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https"] + protocols: ["http", "https", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: host diff --git a/app/_hub/kong-inc/exit-transformer/index.md b/app/_hub/kong-inc/exit-transformer/index.md index c9d30caacddb..27deea94a79a 100644 --- a/app/_hub/kong-inc/exit-transformer/index.md +++ b/app/_hub/kong-inc/exit-transformer/index.md @@ -6,8 +6,8 @@ version: 1.5.x desc: Customize Kong exit responses sent downstream description: | Transform and customize Kong response exit messages using Lua functions. - The capabilities range from changing messages, status codes, and headers, to completely transforming - the structure of Kong responses. + The capabilities range from changing messages, status codes, and headers, + to completely transforming the structure of Kong responses. type: plugin enterprise: true @@ -37,37 +37,87 @@ params: - name: handle_unknown default: "`false`" required: false - description: Allow transform to apply to unmatched route (404) responses. Should not be enabled on more than one plugin configuration. + description: Allow transform to apply to unmatched Service, Route, or Workspace (404) responses. - name: handle_unexpected default: "`false`" required: false - description: Allow transform to apply to unexpected request (400) responses. Should not be enabled on more than one plugin configuration. - - name: handle_admin - default: "`false`" - required: false - description: Allow transform to apply to Admin API responses. Should not be enabled on more than one plugin configuration. + description: Allow transform to apply to unexpected request (400) responses. --- -## Transforming 404 and 400 responses - -By default, the exit transformer is only applied to requests that match its -criteria (its route, service, or consumer matching configuration) or -globally within a workspace. However, requests that result in 400 or 404 -responses neither match any criteria nor fall within any specific workspace, -and standard plugin criteria will never match them. Users can designate exit -transformer configurations that _do_ handle these responses by enabling the -`handle_unknown` (404) and `handle_unexpected` (400) settings. These should -only be enabled on a single plugin configuration. - -`handle_admin` allows the exit transformer to apply to Admin API responses. -Users should only modify headers only applying functions to Admin API -responses, as modifying the body or status will interfere with Kong Manager's -ability to communicate with the Admin API. - -## Function syntax - -The exit transformer expects a configuration function to be Lua code that returns +## Transforming 4xx and 5xx Responses + +By default, the Exit Transformer is only applied to requests that match its +criteria (its Route or Service matching configuration) or globally within a Workspace. + +### Handling Unmatched 400 and 404 Responses + +Requests that result in 400 or 404 responses neither match any criteria nor fall +within any specific Workspace, and standard plugin criteria will never match those +responses. You can designate Exit Transformer configurations that _do_ handle these +responses by enabling the `handle_unexpected` (400) and `handle_unknown` (404) settings: + +- The `handle_unknown` parameter should only be enabled on a single plugin configuration. +- The `handle_unexpected` parameter can be enabled on as many plugin configurations +as you want. + +It's not a prerequisite for `handle_unexpected` to also have `handle_unknown` set, +if an unexpected error happened within some known Service or Route context. If a +configuration has both `handle_unknown` and `handle_unexpected` enabled, then an +unexpected error on an _unknown_ Service or Route will pass through the Exit Transformer plugin. + +### HTTP Response Status Codes {#http-msgs} + +**4xx** codes are client error responses: + +- [400 Bad request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) +- [401 Unauthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) +- [402 Payment required](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/402) +- [403 Forbidden](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403) +- [404 Not found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404) +- [405 Method not allowed](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405) +- [406 Not acceptable](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406) +- [407 Proxy authentication required](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407) +- [408 Request timeout](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) +- [409 Conflict](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409) +- [410 Gone](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/410) +- [411 Length required](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/411) +- [412 Precondition failed](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412) +- [413 Payload too large](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) +- [414 URI too long](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414) +- [415 Unsupported media type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415) +- [416 Range not satisfiable](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416) +- [417 Expectation failed](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/417) +- [418 I'm a teapot](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418) +- [421 Misdirected request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/421) +- [422 Unprocessable entity](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422) +- [423 Locked](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/423) +- [424 Failed dependency](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/424) +- [425 Too early](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/425) +- [426 Upgrade required](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/426) +- [428 Precondition required](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428) +- [429 Too many requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) +- [431 Request header fields too large](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431) +- [451 Unavailable for legal reasons](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451) +- [494 Request header or cookie too large](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/494) + +**5xx** codes are server error responses: + +- [500 An unexpected error occurred](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) +- [501 Not implemented](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501) +- [502 An invalid response was received from the upstream server](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) +- [503 The upstream server is currently unavailable](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) +- [504 The upstream server is timing out](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504) +- [505 HTTP version not supported](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/505) +- [506 Variant also negotiates](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/506) +- [507 Insufficient storage](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/507) +- [508 Loop detected](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508) +- [510 Not extended](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/510) +- [511 Network authentication required](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/511) + +## Function Syntax + +The Exit Transformer plugin expects a configuration function to be Lua code that returns a function accepting three arguments: status, body, and headers. Any Kong exit call exposed on the proxy side gets reduced through these @@ -81,15 +131,16 @@ Kong -> f(status, body, headers) -> ... -> exit(status, body, headers) Warning kong.response.exit() requires a status argument only. body and headers may be nil. - If you manipulate them, first check that they exist and instantiate them - if they do not. The "Modify the body and headers, even if none were provided" - example below shows how to do this. + If you manipulate the body and headers, first check that they exist and + instantiate them if they do not exist.
+If you manipulate body and headers, see the +[Modify the body and headers regardless if provided](#mod-body-head) example below. -### Examples +### Example Lua Functions -* Identity function: does not transform the exit responses +#### Identity function that does not transform the exit responses ```lua return function(status, body, headers) @@ -97,7 +148,7 @@ return function(status, body, headers) end ``` -* Always return a 200 status code, bundling the status within the message +#### Function that always returns a 200 status code with status bundled within the message ```lua return function(status, body, headers) @@ -112,7 +163,7 @@ return function(status, body, headers) end ``` -* Customize particular Kong messages +#### Customize particular Kong messages ```lua local responses = { @@ -142,7 +193,7 @@ return function(status, body, headers) end ``` -* Modify the body and headers, even if none were provided +#### Modify the body and headers regardless if provided {#mod-body-head} ```lua return function(status, body, headers) @@ -164,18 +215,54 @@ end ## Demonstration -1. Create a Service and a Route in Kong: +### Step 1: Create a Service in Kong + + {% navtabs %} + {% navtab Using cURL %} + + ```bash + $ curl -i -X POST http://:8001/services \ + --data name=example.com \ + --data url='http://mockbin.org' + ``` + + {% endnavtab %} + {% navtab Using HTTPie %} + + ```bash + $ http :8001/services name=example.com host=mockbin.org + ``` + + {% endnavtab %} + {% endnavtabs %} + +### Step 2: Create a Route in Kong - ```bash - $ http :8001/services name=example.com host=mockbin.org - $ http -f :8001/services/example.com/routes hosts=example.com - ``` + {% navtabs %} + {% navtab Using cURL %} -2. Create a file named `transform.lua` with the transformation code. The - following example adds a header, appends "arr!" to any message, and adds - an `error` and `status` field on the response. +```bash +$ curl -i -X POST http://:8001/services/example.com/routes \ + --data 'hosts[]=example.com' +``` + + {% endnavtab %} + {% navtab Using HTTPie %} - ```lua +```bash +$ http -f :8001/services/example.com/routes hosts=example.com +``` + + {% endnavtab %} + {% endnavtabs %} + +### Step 3: Create a Transform + +Create a file named `transform.lua` with the transformation code. The +following example adds a header, appends "arr!" to any message, and adds +`error` and `status` fields on the response body. + +```lua -- transform.lua return function(status, body, headers) if not body or not body.message then @@ -189,28 +276,83 @@ end message = body.message .. ", arr!", } - return status, body, headers + return status, new_body, headers end - ``` +``` + +### Step 4: Configure the Plugin with its Transform + +Configure the `exit-transformer` plugin with `transform.lua`. + + {% navtabs %} + {% navtab Using cURL %} + + ```bash + $ curl -X POST http://:8001/services/example.com/plugins \ + -F "name=exit-transformer" \ + -F "config.functions=@transform.lua" + ``` + {% endnavtab %} + {% navtab Using HTTPie %} + + ```bash + $ http -f :8001/services/example.com/plugins \ + name=exit-transformer \ + config.functions=@transform.lua + ``` + + {% endnavtab %} + {% endnavtabs %} + +### Step 5: Configure the Key-Auth Plugin to Test the Exit Transform + +Add the `key-auth` plugin to test a forced generation of an exit transform +response in [step 6](#testy-exit): -3. Configure the `exit-transformer` plugin with `transform.lua` + {% navtabs %} + {% navtab Using cURL %} - ```bash - $ http -f :8001/services/example.com/plugins \ - name=exit-transformer \ - config.functions=@transform.lua - ``` + ```bash + $ curl -X POST http://:8001/services/example.com/plugins \ + --data "name=key-auth" + ``` + + {% endnavtab %} + {% navtab Using HTTPie %} + + ```bash + $ http :8001/services/example.com/plugins name=key-auth + ``` + + {% endnavtab %} + {% endnavtabs %} + +### Step 6: Test a Forced Generation of an Exit Response {#testy-exit} -4. (example) Add key-auth plugin to force generation of an exit response +Attempt a request to the Service to get the custom error. Because the +request did not provide credentials (API key), a 401 response is returned +in the message body. - ```bash - $ http :8001/services/example.com/plugins name=key-auth - ``` +{% navtabs %} +{% navtab Using cURL %} + +```bash +$ curl --header 'Host: example.com' 'localhost:8000' +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +$ http :8000 Host:example.com +``` -5. Attempt a request to the Service to get the custom error +{% endnavtab %} +{% endnavtabs %} - ```bash - $ http :8000 Host:example.com +Response: + +```bash HTTP/1.1 200 OK ... X-Some-Header: some value @@ -220,17 +362,44 @@ end "status": 401, "kong_message": "No API key found in request, arr!" } - ``` +``` -6. Note the plugin can also be applied globally +## More Examples - ```bash - $ http :8001/plugins \ - name=exit-transformer \ - config.handle_unknown=true \ - config.functions=@transform.lua +### Apply the Plugin Globally to Handle Unknown Responses + +The plugin can also be applied globally: + +{% navtabs %} +{% navtab Using cURL %} + +```bash +$ curl -X POST http://:8001/plugins/ \ + -F "name=exit-transformer" \ + -F "config.handle_unknown=true" \ + -F "config.functions=@transform.lua" +... +$ curl --header 'Host: non-existent.com' 'localhost:8000' +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +$ http :8001/plugins \ + name=exit-transformer \ + config.handle_unknown=true \ + config.functions=@transform.lua + +$ http :8000 Host:non-existent.com +``` - $ http :8000 Host:non-existent.com +{% endnavtab %} +{% endnavtabs %} + +Response: + +```bash HTTP/1.1 200 OK ... X-Some-Header: some value @@ -238,6 +407,106 @@ end { "error": true, "status": 404, - "kong_message": "no Route matched with those values, arr!" + "kong_message": "No Route matched with those values, arr!" } - ``` + ``` + +### Custom Errors by MIME Type + +This example shows a use case where you want custom JSON and HTML responses +based on an [Accept header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept). + +Create a file named `custom-errors-by-mimetype.lua` with the transformation +code shown below. Include the status codes you want to customize. See the full list +of HTTP response codes [above](#http-msgs). Any status code not listed in the +`custom-errors-by-mimetype.lua` file will use the default +response `The upstream server responded with `. + +```lua +local template = require "resty.template" +local split = require "kong.tools.utils".split + +local HTTP_MESSAGES = { + s400 = "Bad request", + s401 = "Unauthorized", + -- ... + -- See HTTP Response Status Codes section above for the full list + s511 = "Network authentication required", + default = "The upstream server responded with %d" +} + +local function get_message(status) + return HTTP_MESSAGES["s" .. status] or HTTP_MESSAGES.default.format(status) +end + +local html = template.compile([[ + + + + + Some Title + + +

HTTP {{ status }}

+

{{ error }}

+ + + +]]) + +-- Customize responses based on content type +local formats = { + ["application/json"] = function(status, message, headers) + return status, { status = status, error = message }, headers + end, + ["text/html"] = function(status, message, headers) + return status, html { status = status, error = message }, headers + end, +} + +return function(status, body, headers) + if status < 400 then + return status, body, headers + end + + local accept = kong.request.get_header("accept") + -- Gets just first accept value. Can be improved to be compliant quality + -- etc parser. Look into kong.pdk.response get_response_type + if type(accept) == "table" then + accept = accept[1] + end + accept = split(accept, ",")[1] + + if not formats[accept] then + return status, body, headers + end + + return formats[accept](status, get_message(status), headers) +end +``` + +Configure the `exit-transformer` plugin with `custom-errors-by-mimetype.lua`. + +{% navtabs %} +{% navtab Using cURL %} + +```bash +$ curl -X POST http://:8001/services/example.com/plugins \ + -F "name=exit-transformer" \ + -F "config.handle_unknown=true" \ + -F "config.handle_unexpected=true" \ + -F "config.functions=@examples/custom-errors-by-mimetype.lua" +``` + +{% endnavtab %} +{% navtab Using HTTPie %} + +```bash +$ http -f :8001/plugins name=exit-transformer \ + config.handle_unknown=true \ + config.handle_unexpected=true \ + config.functions=@examples/custom-errors-by-mimetype.lua +``` + +{% endnavtab %} +{% endnavtabs %} diff --git a/app/_hub/kong-inc/file-log/0.1-x.md b/app/_hub/kong-inc/file-log/0.1-x.md index 0109e19c2c31..e8ad472982a5 100644 --- a/app/_hub/kong-inc/file-log/0.1-x.md +++ b/app/_hub/kong-inc/file-log/0.1-x.md @@ -3,14 +3,14 @@ name: File Log publisher: Kong Inc. version: 0.1-x -desc: Append request and response data to a log file on disk +desc: Append request and response data to a log file description: | - Append request and response data to a log file on disk. + Append request and response data in JSON format to a log file. You can also specify + streams (for example, `/dev/stdout` and `/dev/stderr`), which is especially useful + when running Kong in Kubernetes. - It is not recommended to use this plugin in production, it would be better to - use another logging plugin, for example `syslog`, in those cases. Due to system - limitations this plugin uses blocking file i/o, which will hurt performance, - and hence is an anti-pattern for Kong installations. + This plugin uses blocking I/O, which could affect performance when writing + to physical files on slow (spinning) disks.
Note: The functionality of this plugin as bundled diff --git a/app/_hub/kong-inc/file-log/index.md b/app/_hub/kong-inc/file-log/index.md index f07380489561..09b43f41a259 100644 --- a/app/_hub/kong-inc/file-log/index.md +++ b/app/_hub/kong-inc/file-log/index.md @@ -3,14 +3,14 @@ name: File Log publisher: Kong Inc. version: 1.0.0 -desc: Append request and response data to a log file on disk +desc: Append request and response data to a log file description: | - Append request and response data to a log file on disk. + Append request and response data in JSON format to a log file. You can also specify + streams (for example, `/dev/stdout` and `/dev/stderr`), which is especially useful + when running Kong in Kubernetes. - It is not recommended to use this plugin in production, it would be better to - use another logging plugin, for example `syslog`, in those cases. Due to system - limitations this plugin uses blocking file i/o, which will hurt performance, - and hence is an anti-pattern for Kong installations. + This plugin uses blocking I/O, which could affect performance when writing + to physical files on slow (spinning) disks.
Note: The functionality of this plugin as bundled @@ -65,7 +65,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: path diff --git a/app/_hub/kong-inc/forward-proxy/index.md b/app/_hub/kong-inc/forward-proxy/index.md index 03947873e5fa..c4b0a3be4089 100644 --- a/app/_hub/kong-inc/forward-proxy/index.md +++ b/app/_hub/kong-inc/forward-proxy/index.md @@ -41,20 +41,27 @@ params: default: value_in_examples: example.com description: | - The hostname or IP address of the forward proxy to which to connect + The hostname or IP address of the forward proxy to which to connect. - name: proxy_port required: true default: value_in_examples: 80 description: | - The TCP port of the forward proxy to which to connect + The TCP port of the forward proxy to which to connect. - name: proxy_scheme - required: + required: true default: http - value_in_examples: + value_in_examples: http description: | - The proxy scheme to use when connecting. Currently only `http` is supported - + The proxy scheme to use when connecting. Currently only `http` is supported. + - name: https_verify + required: true + default: false + value_in_examples: false + description: | + Whether the server certificate will be verified according to the CA certificates + specified in + [lua_ssl_trusted_certificate](https://www.nginx.com/resources/wiki/modules/lua/#lua-ssl-trusted-certificate). --- ### Notes diff --git a/app/_hub/kong-inc/grpc-gateway/index.md b/app/_hub/kong-inc/grpc-gateway/index.md index aa6e55c757ae..832bdd5541f0 100644 --- a/app/_hub/kong-inc/grpc-gateway/index.md +++ b/app/_hub/kong-inc/grpc-gateway/index.md @@ -1,6 +1,7 @@ --- name: gRPC-gateway publisher: Kong Inc. +version: 0.1.x categories: - transformations @@ -19,6 +20,7 @@ license_type: MIT kong_version_compatibility: community_edition: compatible: + - 2.2.x - 2.1.x enterprise_edition: compatible: diff --git a/app/_hub/kong-inc/grpc-web/0.1.x.md b/app/_hub/kong-inc/grpc-web/0.1.x.md new file mode 100644 index 000000000000..7ba282a727c6 --- /dev/null +++ b/app/_hub/kong-inc/grpc-web/0.1.x.md @@ -0,0 +1,187 @@ +--- +name: gRPC-Web +publisher: Kong Inc. +version: 0.1.x + +categories: + - transformations + +type: plugin + +desc: Allow browser clients to call gRPC services +description: | + A Kong plugin to allow access to a gRPC service via the [gRPC-Web protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2). + Primarily, this means JavaScript browser applications using the [gRPC-Web](https://github.com/grpc/grpc-web) library. + +source_url: https://github.com/Kong/kong-plugin-grpc-web + +license_type: MIT + +kong_version_compatibility: + community_edition: + compatible: + - 2.1.x + + enterprise_edition: + compatible: + - 2.1.x + + +params: + name: grpc-web + route_id: true + protocols: ["http", "https"] + dbless_compatible: true + + config: + - name: proto + required: false + default: + value_in_examples: path/to/hello.proto + description: | + If present, describes the gRPC types and methods. + Required to support payload transcoding. When absent, the + web client must use application/grpw-web+proto content. + +--- + +## Purpose + +A service that presents a gRPC API can be used by clients written in many languages, +but the network specifications are oriented primarily to connections within a +datacenter. [gRPC-Web] lets you expose the gRPC API to the Internet so +that it can be consumed by browser-based JavaScript applications. + +This plugin translates requests and responses between [gRPC-Web] and +[gRPC](https://github.com/grpc/grpc). The plugin supports both HTTP/1.1 +and HTTP/2, over plaintext (HTTP) and TLS (HTTPS) connections. + +## Usage + +This plugin should be enabled on a Kong Route that serves the `http(s)` protocol +but proxies to a Service with the `grpc(s)` protocol. + +Sample configuration via declarative (YAML): + +```yaml +_format_version: "1.1" +services: +- protocol: grpc + host: localhost + port: 9000 + routes: + - protocols: + - http + paths: + - / + plugins: + - name: grpc-web +``` + +Same thing via the Admin API: + +```bash +$ # add the gRPC service +$ curl -XPOST localhost:8001/services \ + --data name=grpc \ + --data protocol=grpc \ + --data host=localhost \ + --data port=9000 + +$ # add an http route +$ curl -XPOST localhost:8001/services/grpc/routes \ + --data protocols=http \ + --data name=web-service \ + --data paths=/ + +$ # add the plugin to the route +$ curl -XPOST localhost:8001/routes/web-service/plugins \ + --data name=grpc-web +``` + +In these examples, we don't set any configuration for the plugin. +This minimal setup works for the default varieties of the [gRPC-Web protocol], +which use ProtocolBuffer messages either directly in binary or with base64-encoding. +The related `Content-Type` headers are `application/grpc-web` or `application/grpc-web+proto` +for binary, and `application/grpc-web-text` or `application/grpc-web-text+proto` for text. + +If you want to use JSON encoding, you have to provide the gRPC specification in +a `.proto` file, which needs to be installed in the Kong node running the plugin. +A path starting with a `/` is considered absolute; otherwise, it will be interpreted +relative to the Kong node's prefix (`/usr/local/kong/` by default). For example: + +```protobuf +syntax = "proto2"; + +package hello; + +service HelloService { + rpc SayHello(HelloRequest) returns (HelloResponse); + rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse); + rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse); + rpc BidiHello(stream HelloRequest) returns (stream HelloResponse); +} + +message HelloRequest { + optional string greeting = 1; +} + +message HelloResponse { + required string reply = 1; +} +``` + +The declarative configuration becomes: + +```yaml +_format_version: "1.1" +services: +- protocol: grpc + host: localhost + port: 9000 + routes: + - protocols: + - http + paths: + - / + plugins: + - name: grpc-web + proto: path/to/hello.proto +``` + +or via the Admin API: + +```bash +$ # add the plugin to the route +$ curl -XPOST localhost:8001/routes/web-service/plugins \ + --data name=grpc-web \ + --data proto=path/to/hello.proto +``` + +With this setup, we can support gRPC-Web/JSON clients using `Content-Type` headers +like `application/grpc-web+json` or `application/grpc-web-text+json`. + +Note that even when using JSON encoding, the [gRPC-Web protocol] specifies that +both request and response data consist of a series of frames, in a similar way +to the full [gRPC protocol]. The [gRPC-Web] library performs this framing as expected. + +As an extension, this plugin also allows naked JSON requests with the POST method and +`Content-Type: application/json` header. These requests are encoded to ProtocolBuffer, +framed, and forwarded to the gRPC service. Likewise, the responses are transformed +on the way back, allowing any HTTP client to use a gRPC service without special +libraries. This feature is limited to unary (non-streaming) requests. Streaming +responses are encoded into multiple JSON objects; it's up to the client to split into +separate records if it has to support multiple response messages. + +## Related information +[Kong]: https://konghq.com +[gRPC protocol]: https://github.com/grpc/grpc +[gRPC-Web]: https://github.com/grpc/grpc-web +[gRPC-Web protocol]: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2 +[lua-protobuf]: https://github.com/starwing/lua-protobuf +[lua-cjson]: https://github.com/openresty/lua-cjson +[lua-pack]: https://github.com/Kong/lua-pack + +## See also + +[Introduction to Kong gRPC plugins](/enterprise/2.1.x/plugins/grpc) diff --git a/app/_hub/kong-inc/grpc-web/index.md b/app/_hub/kong-inc/grpc-web/index.md index 9e6660446b35..e396e7ad1eda 100644 --- a/app/_hub/kong-inc/grpc-web/index.md +++ b/app/_hub/kong-inc/grpc-web/index.md @@ -1,6 +1,7 @@ --- name: gRPC-Web publisher: Kong Inc. +version: 0.2.x categories: - transformations @@ -19,15 +20,13 @@ license_type: MIT kong_version_compatibility: community_edition: compatible: + - 2.2.x - 2.1.x - - 2.0.x - - 1.5.x - - 1.4.x + enterprise_edition: compatible: - 2.1.x - - 1.5.x - - 1.3.x + params: name: grpc-web @@ -42,8 +41,15 @@ params: value_in_examples: path/to/hello.proto description: | If present, describes the gRPC types and methods. - Required to support payload transcoding. When absent, the + Required to support payload transcoding. When absent, the web client must use application/grpw-web+proto content. + - name: pass_stripped_path + required: false + default: + value_in_examples: + description: + If set to `true` causes the plugin to pass the stripped request path to + the upstream gRPC service (see the `strip_path` Route attribute). --- diff --git a/app/_hub/kong-inc/http-log/index.md b/app/_hub/kong-inc/http-log/index.md index b7c1e4fd5829..449646a8c8ed 100644 --- a/app/_hub/kong-inc/http-log/index.md +++ b/app/_hub/kong-inc/http-log/index.md @@ -59,7 +59,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: http_endpoint diff --git a/app/_hub/kong-inc/ip-restriction/0.1-x.md b/app/_hub/kong-inc/ip-restriction/0.1-x.md index 1a6d619015b8..8e39e5d0dfb5 100644 --- a/app/_hub/kong-inc/ip-restriction/0.1-x.md +++ b/app/_hub/kong-inc/ip-restriction/0.1-x.md @@ -44,15 +44,15 @@ params: default: value_in_examples: 54.13.21.1, 143.1.0.0/24 description: | - Comma separated list of IPs or CIDR ranges to whitelist. One of `config.whitelist` or `config.blacklist` must be specified. + Comma-separated list of IPs or CIDR ranges to whitelist. One of `config.whitelist` or `config.blacklist` must be specified. - name: blacklist required: semi default: description: | - Comma separated list of IPs or CIDR ranges to blacklist. One of `config.whitelist` or `config.blacklist` must be specified. + Comma-separated list of IPs or CIDR ranges to blacklist. One of `config.whitelist` or `config.blacklist` must be specified. extra: | - Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure the plugin with both `whitelist` and `blacklist` configurations. An `whitelist` provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. By contrast, a `blacklist` configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). + Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure the plugin with both `whitelist` and `blacklist` configurations. A `whitelist` provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. In contrast, a `blacklist` configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). --- diff --git a/app/_hub/kong-inc/ip-restriction/1.0-x.md b/app/_hub/kong-inc/ip-restriction/1.0-x.md new file mode 100644 index 000000000000..fbb59cb16e78 --- /dev/null +++ b/app/_hub/kong-inc/ip-restriction/1.0-x.md @@ -0,0 +1,69 @@ +--- +name: IP Restriction +publisher: Kong Inc. +version: 1.0-x + +desc: Whitelist or blacklist IPs that can make API requests +description: | + Restrict access to a Service or a Route (or the deprecated API entity) by either whitelisting or blacklisting IP addresses. Single IPs, multiple IPs or ranges in [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) like `10.10.10.0/24` can be used. The plugin supports IPv4 and IPv6 addresses. + +type: plugin +categories: + - security + +kong_version_compatibility: + community_edition: + compatible: + - 1.5.x + - 1.4.x + - 1.3.x + - 1.2.x + - 1.1.x + - 1.0.x + - 0.14.x + - 0.13.x + - 0.12.x + - 0.11.x + - 0.10.x + - 0.9.x + - 0.8.x + - 0.7.x + - 0.6.x + - 0.5.x + - 0.4.x + enterprise_edition: + compatible: + - 1.5.x + - 1.3-x + - 0.36-x + - 0.35-x + - 0.34-x + - 0.33-x + - 0.32-x + - 0.31-x + +params: + name: ip-restriction + service_id: true + route_id: true + consumer_id: true + protocols: ["http", "https"] + dbless_compatible: yes + config: + - name: whitelist + required: semi + default: + value_in_examples: [ "54.13.21.1", "143.1.0.0/24" ] + description: | + Comma-separated list of IPs or CIDR ranges to whitelist. One of `config.whitelist` or `config.blacklist` must be specified. + - name: blacklist + required: semi + default: + description: | + Comma-separated list of IPs or CIDR ranges to blacklist. One of `config.whitelist` or `config.blacklist` must be specified. + + extra: | + + Note that the `whitelist` and `blacklist` models are mutually exclusive in their usage, as they provide complimentary approaches. That is, you cannot configure the plugin with both `whitelist` and `blacklist` configurations. A `whitelist` provides a positive security model, in which the configured CIDR ranges are allowed access to the resource, and all others are inherently rejected. In contrast, a `blacklist` configuration provides a negative security model, in which certain CIDRS are explicitly denied access to the resource (and all others are inherently allowed). + +--- diff --git a/app/_hub/kong-inc/ip-restriction/index.md b/app/_hub/kong-inc/ip-restriction/index.md index 1e02b45edce8..0a36cb142efe 100644 --- a/app/_hub/kong-inc/ip-restriction/index.md +++ b/app/_hub/kong-inc/ip-restriction/index.md @@ -1,7 +1,7 @@ --- name: IP Restriction publisher: Kong Inc. -version: 1.0.0 +version: 2.0.x desc: Allow or deny IPs that can make requests to your Services description: | diff --git a/app/_hub/kong-inc/jwt/0.1-x.md b/app/_hub/kong-inc/jwt/0.1-x.md index 8ab8f29330f4..0ff12f335c53 100644 --- a/app/_hub/kong-inc/jwt/0.1-x.md +++ b/app/_hub/kong-inc/jwt/0.1-x.md @@ -437,7 +437,7 @@ $ curl -i -X POST http://kong:8001/consumers \ $ curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ -F "algorithm=RS256" \ -F "rsa_public_key=@./pubkey.pem" \ - -F "key=https://{COMPAYNAME}.auth0.com/" # the `iss` field + -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field ``` The JWT plugin by default validates the `key_claim_name` against the `iss` @@ -454,8 +454,6 @@ $ curl -i http://localhost:8000 \ -H "Authorization:Bearer {{TOKEN}}" ``` -Success! - ### Upstream Headers When a JWT is valid, a Consumer has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: diff --git a/app/_hub/kong-inc/jwt/2.1-x.md b/app/_hub/kong-inc/jwt/2.1-x.md index 2400b7f37933..11ec54c2c729 100644 --- a/app/_hub/kong-inc/jwt/2.1-x.md +++ b/app/_hub/kong-inc/jwt/2.1-x.md @@ -457,7 +457,7 @@ $ curl -i -X POST http://kong:8001/consumers \ $ curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ -F "algorithm=RS256" \ -F "rsa_public_key=@./pubkey.pem" \ - -F "key=https://{COMPAYNAME}.auth0.com/" # the `iss` field + -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field ``` The JWT plugin by default validates the `key_claim_name` against the `iss` @@ -474,8 +474,6 @@ $ curl -i http://localhost:8000 \ -H "Authorization:Bearer {{TOKEN}}" ``` -Success! - ### Upstream Headers When a JWT is valid, a Consumer has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: diff --git a/app/_hub/kong-inc/jwt/index.md b/app/_hub/kong-inc/jwt/index.md index 42ee8f0261c2..47a4d1cbcc0f 100644 --- a/app/_hub/kong-inc/jwt/index.md +++ b/app/_hub/kong-inc/jwt/index.md @@ -5,13 +5,18 @@ version: 2.2.0 desc: Verify and authenticate JSON Web Tokens description: | - Verify requests containing HS256 or RS256 signed JSON Web Tokens (as specified in [RFC 7519](https://tools.ietf.org/html/rfc7519)). Each of your Consumers will have JWT credentials (public and secret keys) which must be used to sign their JWTs. A token can then be passed through: + Verify requests containing HS256 or RS256 signed JSON Web Tokens (as specified + in [RFC 7519](https://tools.ietf.org/html/rfc7519)). Each of your Consumers + will have JWT credentials (public and secret keys), which must be used to sign + their JWTs. A token can then be passed through: - - a query string parameter, - - a cookie, - - or HTTP request headers + - a query string parameter + - a cookie + - HTTP request headers - Kong will either proxy the request to your upstream services if the token's signature is verified, or discard the request if not. Kong can also perform verifications on some of the registered claims of RFC 7519 (exp and nbf). + Kong will either proxy the request to your Upstream services if the token's + signature is verified, or discard the request if not. Kong can also perform + verifications on some of the registered claims of RFC 7519 (exp and nbf).
Note: The functionality of this plugin as bundled @@ -69,7 +74,7 @@ params: dbless_explanation: | Consumers and JWT secrets can be created with declarative configuration. - Admin API endpoints which do POST, PUT, PATCH or DELETE on secrets are not available on DB-less mode. + Admin API endpoints that do POST, PUT, PATCH, or DELETE on secrets are not available on DB-less mode. config: - name: uri_param_names required: false @@ -102,42 +107,45 @@ params: required: false default: description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. + An optional string (consumer uuid) value to use as an anonymous consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. The anonymous value must refer to the Consumer `id` attribute that is internal to Kong, and **not** its `custom_id`. - name: run_on_preflight required: false default: "`true`" description: | - A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests, if set to `false` then `OPTIONS` requests will always be allowed. + A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false`, then `OPTIONS` requests will always be allowed. - name: maximum_expiration required: false default: 0 description: | - An integer limiting the lifetime of the JWT to `maximum_expiration` seconds in the future. Any JWT that has a longer lifetime will rejected (HTTP 403). If this value is specified, `exp` must be specified as well in the `claims_to_verify` property. The default value of `0` represents an indefinite period. Potential clock skew should be considered when configuring this setting. + An integer limiting the lifetime of the JWT to `maximum_expiration` seconds in the future. Any JWT that has a longer lifetime is rejected (HTTP 403). If this value is specified, `exp` must be specified as well in the `claims_to_verify` property. The default value of `0` represents an indefinite period. Potential clock skew should be considered when configuring this setting. extra: |
-
The option `config.run_on_preflight` is only available from version `0.11.1` and later
+
The option config.run_on_preflight is only available from version 0.11.1 and later.
--- ## Documentation -In order to use the plugin, you first need to create a Consumer and associate one or more JWT credentials (holding the public and private keys used to verify the token) to it. The Consumer represents a developer using the final service. +To use the plugin, you first need to create a Consumer and associate one or more +JWT credentials (holding the public and private keys used to verify the token) to it. +The Consumer represents a developer using the final service. ### Create a Consumer You need to associate a credential to an existing [Consumer][consumer-object] object. A Consumer can have many credentials. -{% tabs %} -{% tab With a Database %} +{% navtabs %} +{% navtab Kong Admin API %} To create a Consumer, you can execute the following request: ```bash curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://kong:8001/consumers/ ``` -{% tab Without a Database %} +{% endnavtab %} +{% navtab Declarative (YAML) %} Your declarative configuration file will need to have one or more Consumers. You can create them on the `consumers:` yaml section: @@ -146,7 +154,8 @@ consumers: - username: user123 custom_id: SOME_CUSTOM_ID ``` -{% endtabs %} +{% endnavtab %} +{% endnavtabs %} In both cases, the parameters are as described below: @@ -158,8 +167,8 @@ parameter | description ### Create a JWT credential -{% tabs %} -{% tab With a database %} +{% navtabs %} +{% navtab Kong Admin API %} You can provision a new HS256 JWT credential by issuing the following HTTP request: ```bash @@ -174,16 +183,18 @@ HTTP/1.1 201 Created "secret": "e71829c351aa4242c2719cbfbe671c09" } ``` -{% tab Without a database %} +{% endnavtab %} +{% navtab Declarative (YAML) %} You can add JWT credentials on your declarative config file on the `jwt_secrets:` yaml entry: ``` yaml jwt_secrets: - consumer: {consumer} ``` -{% endtabs %} +{% endnavtab %} +{% endnavtabs %} -In both cases the fields/parameters work as follows: +In both cases, the fields/parameters work as follows: field/parameter | default | description --- | --- | --- @@ -252,7 +263,8 @@ HTTP/1.1 200 OK ### Craft a JWT with a secret (HS256) -Now that your Consumer has a credential, and assuming we want to sign it using `HS256`, the JWT should be crafted as follows (according to [RFC 7519](https://tools.ietf.org/html/rfc7519)): +Now that your Consumer has a credential, and assuming you want to sign it using `HS256`, +the JWT should be crafted as follows (according to [RFC 7519](https://tools.ietf.org/html/rfc7519)): First, its header must be: @@ -266,7 +278,7 @@ First, its header must be: Secondly, the claims **must** contain the secret's `key` in the configured claim (from `config.key_claim_name`). That claim is `iss` (issuer field) by default. Set its value to our previously created credential's `key`. The claims may contain other values. Since Kong `0.13.1`, the claim is searched in both the JWT payload and header, -in this order. +in that order. ```json { @@ -274,7 +286,8 @@ in this order. } ``` -Using the JWT debugger at https://jwt.io with the header (HS256), claims (iss, etc), and `secret` associated with this `key` (e71829c351aa4242c2719cbfbe671c09), you'll end up with a JWT token of: +Using the JWT debugger at https://jwt.io with the header (HS256), claims (iss, etc.), +and `secret` associated with this `key` (e71829c351aa4242c2719cbfbe671c09), you'll end up with a JWT token of: ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4 @@ -325,7 +338,7 @@ valid signature, invalid verified claim _optional_ | no | Kong can also perform verification on registered claims, as defined in [RFC 7519](https://tools.ietf.org/html/rfc7519). To perform verification on a claim, add it to the `config.claims_to_verify` property: -You can patch an existing jwt plugin: +You can patch an existing JWT plugin: ```bash # This adds verification for both nbf and exp claims: @@ -337,12 +350,13 @@ Supported claims: claim name | verification -----------|------------- -`exp` | identifies the expiration time on or after which the JWT must not be accepted for processing. -`nbf` | identifies the time before which the JWT must not be accepted for processing. +`exp` | Identifies the expiration time on or after which the JWT must not be accepted for processing. +`nbf` | Identifies the time before which the JWT must not be accepted for processing. -### (Optional) Base64 encoded secret +### (Optional) Base64-encoded secret -If your secret contains binary data, you can store them as base64 encoded in Kong. Enable this option in the plugin's configuration: +If your secret contains binary data, you can store them as base64 encoded in Kong. +Enable this option in the plugin's configuration. You can patch an existing Route: @@ -351,7 +365,7 @@ $ curl -X PATCH http://kong:8001/routes/{route id}/plugins/{jwt plugin id} \ --data "config.secret_is_base64=true" ``` -Then, base64 encode your consumers' secrets: +Then, base64 encode your Consumers' secrets: ```bash # secret is: "blob data" @@ -363,7 +377,9 @@ And sign your JWT using the original secret ("blob data"). ### Craft a JWT with public/private keys (RS256 or ES256) -If you wish to use RS256 or ES256 to verify your JWTs, then when creating a JWT credential, select `RS256` or `ES256` as the `algorithm`, and explicitly upload the public key in the `rsa_public_key` field (including for ES256 signed tokens). For example: +If you want to use RS256 or ES256 to verify your JWTs, then when creating a JWT credential, +select `RS256` or `ES256` as the `algorithm`, and explicitly upload the public key +in the `rsa_public_key` field (including for ES256 signed tokens). For example: ```bash $ curl -X POST http://kong:8001/consumers/{consumer}/jwt \ @@ -391,8 +407,8 @@ When creating the signature, make sure that the header is: Secondly, the claims **must** contain the secret's `key` field (this **isn't** your private key used to generate the token, but just an identifier for this credential) in the configured claim (from `config.key_claim_name`). That claim is `iss` (issuer field) by default. Set its value to our previously created credential's `key`. -The claims may contain other values. Since Kong `0.13.1`, the claim is searched in both the JWT payload and header, -in this order. +The claims may contain other values. Since Kong version `0.13.1`, the claim is searched in both the JWT payload and header, +in that order. ```json { @@ -400,7 +416,9 @@ in this order. } ``` -Then create the signature using your private keys. Using the JWT debugger at https://jwt.io, set the right header (RS256), the claims (iss, etc), and the associated public key. Then append the resulting value in the `Authorization` header, for example: +Then, create the signature using your private keys. Using the JWT debugger at +[https://jwt.io](https://jwt.io), set the right header (RS256), the claims (iss, etc.), and the +associated public key. Then, append the resulting value in the `Authorization` header, for example: ```bash $ curl http://kong:8000/{route path} \ @@ -409,7 +427,7 @@ $ curl http://kong:8000/{route path} \ ### Generate public/private keys -To create a brand new pair of public/private keys, you can run the following command: +To create a brand new pair of public/private keys, run the following command: ```bash $ openssl genrsa -out private.pem 2048 @@ -421,24 +439,26 @@ This private key must be kept secret. To generate a public key corresponding to $ openssl rsa -in private.pem -outform PEM -pubout -out public.pem ``` -If you run the commands above, the public key will be written in `public.pem`, while the private key will be written in `private.pem`. +If you run the commands above, the public key is written to `public.pem`, whereas the +private key is written to `private.pem`. ### Using the JWT plugin with Auth0 [Auth0](https://auth0.com/) is a popular solution for Authorization, and relies heavily on JWTs. Auth0 relies on RS256, does not base64 encode, and publicly hosts the public key certificate used to sign tokens. Account name is referred -to "COMPANYNAME" for the sake of the guide. +to as `{COMPANYNAME}` for the sake of the following examples. To get started, create a Service and a Route that uses that Service. -_Note: Auth0 does not use base64 encoded secrets._ + +_Note: Auth0 does not use base64-encoded secrets._ Create a Service: ```bash $ curl -i -f -X POST http://localhost:8001/services \ --data "name=example-service" \ - --data "=http://httpbin.org" + --data "url=http://httpbin.org" ``` Then create a Route: @@ -449,7 +469,7 @@ $ curl -i -f -X POST http://localhost:8001/routes \ --data "paths[]=/example_path" ``` -Add the JWT Plugin: +#### Add the JWT Plugin Add the plugin to your Route: @@ -461,7 +481,7 @@ $ curl -X POST http://localhost:8001/route/{route id}/plugins \ Download your Auth0 account's X509 Certificate: ```bash -$ curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.auth0.com/pem +$ curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.{REGION-ID}.auth0.com/pem ``` Extract the public key from the X509 Certificate: @@ -480,7 +500,7 @@ $ curl -i -X POST http://kong:8001/consumers \ $ curl -i -X POST http://localhost:8001/consumers/{consumer}/jwt \ -F "algorithm=RS256" \ -F "rsa_public_key=@./pubkey.pem" \ - -F "key=https://{COMPAYNAME}.auth0.com/" # the `iss` field + -F "key=https://{COMPANYNAME}.auth0.com/" # the `iss` field ``` The JWT plugin by default validates the `key_claim_name` against the `iss` @@ -489,27 +509,29 @@ field in the token. Keys issued by Auth0 have their `iss` field set to validate the `iss` field for the `key` parameter when creating the Consumer. -Send requests through, only tokens signed by Auth0 will work: +Send requests through. Only tokens signed by Auth0 will work: ```bash $ curl -i http://localhost:8000 \ -H "Host:example.com" \ - -H "Authorization:Bearer {{TOKEN}}" + -H "Authorization:Bearer " ``` -Success! - ### Upstream Headers -When a JWT is valid, a Consumer has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the Consumer in your code: +When a JWT is valid and a Consumer has been authenticated, the plugin appends +some headers to the request before proxying it to the Upstream service +so that you can identify the Consumer in your code: -* `X-Consumer-ID`, the ID of the Consumer on Kong -* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set) -* `X-Consumer-Username`, the `username` of the Consumer (if set) -* `X-Credential-Identifier`, the identifier of the credential (if set) -* `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. +* `X-Consumer-ID`, the ID of the Consumer on Kong. +* `X-Consumer-Custom-ID`, the `custom_id` of the Consumer (if set). +* `X-Consumer-Username`, the `username` of the Consumer (if set). +* `X-Credential-Identifier`, the identifier of the credential (if set). +* `X-Anonymous-Consumer`, set to `true` when authentication failed, and + the `anonymous` consumer was set instead. -You can use this information on your side to implement additional logic. You can use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. +You can use this information on your side to implement additional logic. You can +use the `X-Consumer-ID` value to query the Kong Admin API and retrieve more information about the Consumer. ### Paginate through the JWTs @@ -575,7 +597,7 @@ $ curl -X GET http://kong:8001/consumers/{username or id}/jwt } ``` -`username or id`: The username or id of the consumer whose jwts need to be listed +`username or id`: The username or id of the Consumer whose JWTs need to be listed. ### Retrieve the Consumer associated with a JWT @@ -584,7 +606,7 @@ $ curl -X GET http://kong:8001/consumers/{username or id}/jwt Note: This endpoint was introduced in Kong 0.11.2.
-It is possible to retrieve a [Consumer][consumer-object] associated with a JWT +Retrieve a [Consumer][consumer-object] associated with a JWT using the following request: ```bash diff --git a/app/_hub/kong-inc/kong-terraform-aws/index.md b/app/_hub/kong-inc/kong-terraform-aws/index.md index f4badb42ea2f..3cebb5828631 100644 --- a/app/_hub/kong-inc/kong-terraform-aws/index.md +++ b/app/_hub/kong-inc/kong-terraform-aws/index.md @@ -28,19 +28,7 @@ kong_version_compatibility: - 1.0.x - 0.14.x - 0.13.x -# incompatible: -# - 0.13.x -# - 0.12.x -# - 0.11.x -# - 0.10.x -# - 0.9.x -# - 0.8.x -# - 0.7.x -# - 0.6.x -# - 0.5.x -# - 0.4.x -# - 0.3.x -# - 0.2.x + enterprise_edition: compatible: - 2.1.x @@ -51,11 +39,7 @@ kong_version_compatibility: - 0.34-x - 0.33-x - 0.32-x -# incompatible: -# - 0.32-x -# - 0.31-x -# - 0.30-x -# - 0.29-x + ############################################################################### # END YAML DATA @@ -71,4 +55,5 @@ kong_version_compatibility: ### Documentation -Details, prerequisites, and usage examples are provided at https://github.com/kong/kong-terraform-aws +Details, prerequisites, and usage examples are provided on GitHub at +[https://github.com/kong/kong-terraform-aws](https://github.com/kong/kong-terraform-aws). diff --git a/app/_hub/kong-inc/ldap-auth-advanced/index.md b/app/_hub/kong-inc/ldap-auth-advanced/index.md index d788d6ebba2e..7638cbfe6d10 100644 --- a/app/_hub/kong-inc/ldap-auth-advanced/index.md +++ b/app/_hub/kong-inc/ldap-auth-advanced/index.md @@ -4,9 +4,11 @@ name: LDAP Authentication Advanced publisher: Kong Inc. version: 1.3-x -desc: Secure Kong clusters, routes and services with username and password protection +desc: Secure Kong clusters, Routes, and Services with username and password protection description: | - Add LDAP Bind Authentication with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). + Add LDAP Bind Authentication with username and password protection. The plugin + checks for valid credentials in the `Proxy-Authorization` and `Authorization` headers + (in that order). enterprise: true type: plugin @@ -31,86 +33,94 @@ params: service_id: true route_id: true consumer_id: false + protocols: ["http", "https", "gprc", "grpcs"] + dbless_compatible: yes config: - name: ldap_host required: true default: value_in_examples: ldap.example.com description: | - Host on which the LDAP server is running + Host on which the LDAP server is running. - name: ldap_port - required: - default: - value_in_examples: + required: true + default: 389 + value_in_examples: 389 description: | - TCP port where the LDAP server is listening + TCP port where the LDAP server is listening. 389 is the default + port for non-SSL LDAP and AD. 686 is the port required for SSL LDAP and AD. If `ldaps` is + configured, you must use port 686. - name: ldap_password required: default: value_in_examples: description: | - The password to the LDAP server + The password to the LDAP server. - name: start_tls - required: + required: true default: "`false`" - value_in_examples: + value_in_examples: true description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection + Set it to `true` to issue StartTLS (Transport Layer Security) extended operation + over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` + setting is disabled. - name: ldaps - required: + required: true default: "`false`" value_in_examples: description: | Set it to `true` to use `ldaps`, a secure protocol (that can be configured - to TLS) to connect to the LDAP server. + to TLS) to connect to the LDAP server. When `ldaps` is + configured, you must use port 686. If the `ldap` setting is enabled, ensure the + `start_tls` setting is disabled. - name: base_dn required: true default: value_in_examples: dc=example,dc=com description: | - Base DN as the starting point for the search; e.g., "dc=example,dc=com" + Base DN as the starting point for the search; e.g., "dc=example,dc=com". - name: verify_ldap_host - required: + required: true default: "`false`" - value_in_examples: + value_in_examples: false description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. + Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - name: attribute required: true default: value_in_examples: cn description: | - Attribute to be used to search the user; e.g., "cn" + Attribute to be used to search the user; e.g., "cn". - name: cache_ttl - required: + required: true default: "`60`" - value_in_examples: + value_in_examples: 60 description: | - Cache expiry time in seconds + Cache expiry time in seconds. - name: timeout required: false default: "`10000`" value_in_examples: description: | - An optional timeout in milliseconds when waiting for connection with LDAP server + An optional timeout in milliseconds when waiting for connection with LDAP server. - name: keepalive required: false default: "`10000`" value_in_examples: description: | - An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed + An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed. - name: anonymous required: false default: value_in_examples: description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. + An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. The value must refer to the Consumer `id` attribute that is internal to Kong, **not** its `custom_id`. - name: header_type required: false default: "`ldap`" - value_in_examples: + value_in_examples: ldap description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. + An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic", then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. - name: consumer_optional required: false default: "`false`" @@ -122,7 +132,7 @@ params: default: '`[ "username", "custom_id" ]`' value_in_examples: description: | - Whether to authenticate consumer based on `username` and/or `custom_id` + Whether to authenticate Consumers based on `username` and/or `custom_id`. - name: hide_credentials required: false default: "`false`" @@ -134,14 +144,14 @@ params: default: value_in_examples: description: | - The DN to bind to. Used to perform LDAP search of user. This bind_dn + The DN to bind to. Used to perform LDAP search of user. This `bind_dn` should have permissions to search for the user being authenticated. - name: group_base_dn required: default: "matches `conf.base_dn`" value_in_examples: description: | - Sets a distinguished name for the entry where LDAP searches for groups begin. + Sets a distinguished name (DN) for the entry where LDAP searches for groups begin. - name: group_name_attribute required: default: "matches `conf.attribute`" @@ -158,22 +168,31 @@ params: --- -### Usage +## Usage -In order to authenticate the user, client must set credentials in -`Proxy-Authorization` or `Authorization` header in following format: +To authenticate a user, the client must set credentials in either the +`Proxy-Authorization` or `Authorization` header in the following format: credentials := [ldap | LDAP] base64(username:password) -The plugin will validate the user against the LDAP server and cache the -credential for future requests for the duration specified in +The Authorization header would look something like: + + Authorization: ldap dGxibGVzc2luZzpLMG5nU3RyMG5n + +The plugin validates the user against the LDAP server and caches the +credentials for future requests for the duration specified in `config.cache_ttl`. -#### Upstream Headers +You can set the header type `ldap` to any string (such as `basic`) using +`config.header_type`. -When a client has been authenticated, the plugin will append some headers to the - request before proxying it to the upstream service, so that you can identify - the consumer in your code: + + +### Upstream Headers + +When a client has been authenticated, the plugin appends some headers to the +request before proxying it to the upstream service so that you can identify +the consumer in your code: * `X-Credential-Username`, the `username` of the Credential (only if the consumer is not the 'anonymous' consumer) @@ -187,11 +206,11 @@ authentication failed and 'anonymous' was set) authentication failed and 'anonymous' was set) -#### LDAP Search and config.bind_dn +### LDAP Search and `config.bind_dn` LDAP directory searching is performed during the request/plugin lifecycle. It is used to retrieve the fully qualified DN of the user so a bind -request can be performed with the user's given LDAP username and password. The +request can be performed with a user's given LDAP username and password. The search for the user being authenticated uses the `config.bind_dn` property. The search uses `scope="sub"`, `filter="="`, and `base_dn=`. Here is an example of how it performs the search @@ -206,3 +225,8 @@ $ ldapsearch -x -h "" -D "" -b [configuration]: /latest/configuration [consumer-object]: /latest/admin-api/#consumer-object [faq-authentication]: /about/faq/#how-can-i-add-an-authentication-layer-on-a-microservice/api? + + +### Using Service Directory Mapping on the CLI + +{% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} diff --git a/app/_hub/kong-inc/ldap-auth/index.md b/app/_hub/kong-inc/ldap-auth/index.md index 48e5dd3c6c0e..5c33727297ef 100644 --- a/app/_hub/kong-inc/ldap-auth/index.md +++ b/app/_hub/kong-inc/ldap-auth/index.md @@ -3,9 +3,11 @@ name: LDAP Authentication publisher: Kong Inc. version: 2.2.0 -desc: Integrate Kong with a LDAP server +desc: Integrate Kong with an LDAP server description: | - Add LDAP Bind Authentication to a Route with username and password protection. The plugin will check for valid credentials in the `Proxy-Authorization` and `Authorization` header (in this order). + Add LDAP Bind Authentication to a Route with username and password protection. The plugin + checks for valid credentials in the `Proxy-Authorization` and `Authorization` headers + (in that order).
Note: The functionality of this plugin as bundled @@ -69,34 +71,40 @@ params: description: Host on which the LDAP server is running. - name: ldap_port required: true - default: + default: 389 value_in_examples: 389 - description: TCP port where the LDAP server is listening. + description: TCP port where the LDAP server is listening. 389 is the default + port for non-SSL LDAP and AD. 686 is the port required for SSL LDAP and AD. If `ldaps` is + configured, you must use port 686. - name: start_tls required: true default: "`false`" description: | - Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection. + Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` + connection. If the `start_tls` setting is enabled, ensure the `ldaps` + setting is disabled. - name: ldaps required: true default: "`false`" description: | - Set it to `true` to connect using the LDAPS protocol (LDAP over TLS) + Set to `true` to connect using the LDAPS protocol (LDAP over TLS). When `ldaps` is + configured, you must use port 686. If the `ldap` setting is enabled, ensure the + `start_tls` setting is disabled. - name: base_dn required: true default: value_in_examples: dc=example,dc=com - description: Base DN as the starting point for the search. + description: Base DN as the starting point for the search; e.g., "dc=example,dc=com". - name: verify_ldap_host required: true default: "`false`" description: | - Set it to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. + Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive. - name: attribute required: true default: value_in_examples: cn - description: Attribute to be used to search the user. + description: Attribute to be used to search the user; e.g., "cn". - name: cache_ttl required: true default: "`60`" @@ -108,36 +116,50 @@ params: - name: keepalive required: false default: "`60000`" - description: An optional value in milliseconds that defines for how long an idle connection to LDAP server will live before being closed. + description: An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed. - name: anonymous required: false default: description: | - An optional string (consumer uuid) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` attribute which is internal to Kong, and **not** its `custom_id`. + An optional string (consumer UUID) value to use as an "anonymous" consumer if authentication fails. If empty (default), the request will fail with an authentication failure `4xx`. The value must refer to the Consumer `id` attribute that is internal to Kong, **not** its `custom_id`. - name: header_type required: false default: "`ldap`" value_in_examples: ldap description: | - An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic" then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. + An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to "basic", then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `"ldap"` and `"basic"`. extra:
- Note: The config.header_type option was introduced in Kong 0.12.0. Previous versions of this plugin behave as if ldap was set for this value. + Note: The config.header_type option was + introduced in Kong 0.12.0. Previous versions of this plugin behave as if + ldap was set for this value.
--- ## Usage -In order to authenticate the user, client must set credentials in `Proxy-Authorization` or `Authorization` header in following format +To authenticate a user, the client must set credentials in either the +`Proxy-Authorization` or `Authorization` header in the following format: credentials := [ldap | LDAP] base64(username:password) -The plugin will validate the user against the LDAP server and cache the credential for future requests for the duration specified in `config.cache_ttl`. +The Authorization header would look something like: + + Authorization: ldap dGxibGVzc2luZzpLMG5nU3RyMG5n + +The plugin validates the user against the LDAP server and caches the +credentials for future requests for the duration specified in +`config.cache_ttl`. + +You can set the header type `ldap` to any string (such as `basic`) using +`config.header_type`. ### Upstream Headers -When a client has been authenticated, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the consumer in your code: +When a client has been authenticated, the plugin appends some headers to the +request before proxying it to the upstream service so that you can identify +the consumer in your code: * `X-Anonymous-Consumer`, will be set to `true` when authentication failed, and the 'anonymous' consumer was set instead. * `X-Consumer-ID`, the ID of the 'anonymous' consumer on Kong (only if authentication failed and 'anonymous' was set) @@ -152,3 +174,8 @@ When a client has been authenticated, the plugin will append some headers to the [configuration]: /latest/configuration [consumer-object]: /latest/admin-api/#consumer-object [faq-authentication]: /about/faq/#how-can-i-add-an-authentication-layer-on-a-microservice/api? + + +### Using Service Directory Mapping on the CLI + +{% include /md/2.1.x/ldap/ldap-service-directory-mapping.md %} diff --git a/app/_hub/kong-inc/loggly/index.md b/app/_hub/kong-inc/loggly/index.md index 27fa4f9def74..97ddab96a14f 100644 --- a/app/_hub/kong-inc/loggly/index.md +++ b/app/_hub/kong-inc/loggly/index.md @@ -48,7 +48,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: host diff --git a/app/_hub/kong-inc/mtls-auth/1.3-x.md b/app/_hub/kong-inc/mtls-auth/1.3-x.md index 9092c8e9c0c6..97b9d8ad6cec 100644 --- a/app/_hub/kong-inc/mtls-auth/1.3-x.md +++ b/app/_hub/kong-inc/mtls-auth/1.3-x.md @@ -51,7 +51,7 @@ params: Certificate property which will be used as authenticated group. Once `skip_consumer_lookup` is applied, any client with a valid certificate can access the Service/API. To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create whitelist or blacklist groups of users. --- -### Usage +## Usage In order to authenticate the **Consumer**, it must provide a valid certificate and complete mutual TLS handshake with Kong. @@ -96,17 +96,31 @@ The `id` value returned can now be used for mTLS plugin configurations or consum ### Create manual mappings between certificate and Consumer object -Sometimes you may not wish to use automatic Consumer lookup or you have certificates -that contain a field value not associated with **Consumer** objects directly. In those +Sometimes, you might not want to use automatic Consumer lookup, or you have certificates +that contain a field value not directly associated with **Consumer** objects. In those situations, you may manually assign one or more subject names to the **Consumer** object for identifying the correct Consumer. -**Note:** "Subject names" refers to the certificate's Subject Alternative Names (SAN) or +> **Note:** "Subject names" refers to the certificate's Subject Alternative Names (SAN) or "Common Name" (CN). CN will only be used if the SAN extension does not exist. +{% navtabs %} +{% navtab Kong Admin API %} + +Create a mapping: + ```bash $ curl -X POST http://kong:8001/consumers/{consumer}/mtls-auth \ -d 'subject_name=test@example.com' +``` + +Where `{consumer}` is the `id` or `username` property of the +[Consumer](/enterprise/latest/admin-api/#consumer-object) entity to associate the +credentials to. + +Once created, you'll see a `201` success message: + +```bash HTTP/1.1 201 Created { @@ -116,23 +130,49 @@ HTTP/1.1 201 Created } ``` -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. +{% endnavtab %} +{% navtab Declarative (YAML) %} + +To create a subject name mapping using declarative configuration, you will need +to generate a UUID for each `mtls_auth_credentials` mapping. You can use any +UUID generator to do this. Here are some common ones, depending on your OS: +* [Linux](https://man7.org/linux/man-pages/man1/uuidgen.1.html) +* [MacOS](https://www.unix.com/man-page/mojave/1/uuidgen/) +* [Windows](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-guid?view=powershell-7) + +After you have generated a UUID, add the following to your declarative +configuration file: + +```yaml +consumers: +- custom_id: my-consumer + username: {consumer} + mtls_auth_credentials: + - id: bda09448-3b10-4da7-a83b-2a8ba6021f0c + subject_name: test@example.com +``` + +{% endnavtab %} +{% endnavtabs %} -form parameter | default | description ---- | --- | --- -`subject_name`
*required* | | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to `consumer` (in that order of lookup). -`ca_certificate`
*optional* | | UUID of the Certificate Authority (CA) that the certificate has to be verifiable by for the mapping to success. This is to help distinguish multiple certificates with the same subject name but are issued under different CAs. If empty, the subject name will match certificates issued by any CA under the corresponding `config.ca_certificates`. +#### Parameters for manual mapping + +Form Parameter | Default | Description +--- | --- | --- +`id`
*required for declarative config* | none | UUID of the Consumer-mapping. Required if adding mapping using declarative configuration, otherwise generated automatically by Kong's Admin API. +`subject_name`
*required* | none | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to `consumer` (in order of lookup). +`ca_certificate`
*optional* | none | **If using the Kong Admin API:** UUID of the Certificate Authority (CA).

**If using declarative configuration:** Full PEM-encoded CA certificate.

The provided CA UUID or full certificate has to be verifiable by the issuing certificate authority for the mapping to succeed. This is to help distinguish multiple certificates with the same subject name that are issued under different CAs.

If empty, the subject name will match certificates issued by any CA under the corresponding `config.ca_certificates`. ### Matching behaviors -Once a client certificate has been verified as valid, the **Consumer** object will be determined in the following order unless `skip_consumer_lookup` is set to `true`: +After a client certificate has been verified as valid, the **Consumer** object is determined in the following order, unless `skip_consumer_lookup` is set to `true`: 1. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = ` 2. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = NULL` 3. If `config.consumer_by` is not null, Consumer with `username` and/or `id` matching the certificate's SAN or CN (in that order) 4. The `config.anonymous` consumer (if set) -**Note**: matching will stop as soon as the first successful match is found. +> **Note**: Matching stops as soon as the first successful match is found. When a client has been authenticated, the plugin will append headers to the request before proxying it to the upstream service so that you can identify the **Consumer** in your code: @@ -153,13 +193,7 @@ certificate property being set in `authenticated_group_by`. ### Troubleshooting -When authentication fails, the client does not have access to any details explaining the +When authentication fails, the client does not have access to any details that explain the failure. The security reason for this omission is to prevent malicious reconnaissance. Instead, the details are recorded inside Kong's error logs under the `[mtls-auth]` filter. - - -[configuration]: /latest/configuration -[consumer-object]: /latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers -[faq-authentication]: /about/faq/#how-can-i-add-an-authentication-layer-on-a-microservice/api? diff --git a/app/_hub/kong-inc/mtls-auth/index.md b/app/_hub/kong-inc/mtls-auth/index.md index cae05c9106e4..e87d23293e77 100644 --- a/app/_hub/kong-inc/mtls-auth/index.md +++ b/app/_hub/kong-inc/mtls-auth/index.md @@ -68,7 +68,7 @@ params: --- -### Usage +## Usage In order to authenticate the **Consumer**, it must provide a valid certificate and complete mutual TLS handshake with Kong. @@ -113,17 +113,31 @@ The `id` value returned can now be used for mTLS plugin configurations or consum ### Create manual mappings between certificate and Consumer object -Sometimes you may not wish to use automatic Consumer lookup or you have certificates -that contain a field value not associated with **Consumer** objects directly. In those +Sometimes, you might not want to use automatic Consumer lookup, or you have certificates +that contain a field value not directly associated with **Consumer** objects. In those situations, you may manually assign one or more subject names to the **Consumer** object for identifying the correct Consumer. -**Note:** "Subject names" refers to the certificate's Subject Alternative Names (SAN) or +> **Note:** "Subject names" refers to the certificate's Subject Alternative Names (SAN) or "Common Name" (CN). CN will only be used if the SAN extension does not exist. +{% navtabs %} +{% navtab Kong Admin API %} + +Create a mapping: + ```bash $ curl -X POST http://kong:8001/consumers/{consumer}/mtls-auth \ -d 'subject_name=test@example.com' +``` + +Where `{consumer}` is the `id` or `username` property of the +[Consumer](/enterprise/latest/admin-api/#consumer-object) entity to associate the +credentials to. + +Once created, you'll see a `201` success message: + +```bash HTTP/1.1 201 Created { @@ -133,23 +147,49 @@ HTTP/1.1 201 Created } ``` -* `consumer`: The `id` or `username` property of the [Consumer][consumer-object] entity to associate the credentials to. +{% endnavtab %} +{% navtab Declarative (YAML) %} + +To create a subject name mapping using declarative configuration, you will need +to generate a UUID for each `mtls_auth_credentials` mapping. You can use any +UUID generator to do this. Here are some common ones, depending on your OS: +* [Linux](https://man7.org/linux/man-pages/man1/uuidgen.1.html) +* [MacOS](https://www.unix.com/man-page/mojave/1/uuidgen/) +* [Windows](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-guid?view=powershell-7) + +After you have generated a UUID, add the following to your declarative +configuration file: + +```yaml +consumers: +- custom_id: my-consumer + username: {consumer} + mtls_auth_credentials: + - id: bda09448-3b10-4da7-a83b-2a8ba6021f0c + subject_name: test@example.com +``` + +{% endnavtab %} +{% endnavtabs %} -form parameter | default | description ---- | --- | --- -`subject_name`
*required* | | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to `consumer` (in that order of lookup). -`ca_certificate`
*optional* | | UUID of the Certificate Authority (CA) that the certificate has to be verifiable by for the mapping to success. This is to help distinguish multiple certificates with the same subject name but are issued under different CAs. If empty, the subject name will match certificates issued by any CA under the corresponding `config.ca_certificates`. +#### Parameters for manual mapping + +Form Parameter | Default | Description +--- | --- | --- +`id`
*required for declarative config* | none | UUID of the Consumer-mapping. Required if adding mapping using declarative configuration, otherwise generated automatically by Kong's Admin API. +`subject_name`
*required* | none | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to `consumer` (in order of lookup). +`ca_certificate`
*optional* | none | **If using the Kong Admin API:** UUID of the Certificate Authority (CA).

**If using declarative configuration:** Full PEM-encoded CA certificate.

The provided CA UUID or full certificate has to be verifiable by the issuing certificate authority for the mapping to succeed. This is to help distinguish multiple certificates with the same subject name that are issued under different CAs.

If empty, the subject name will match certificates issued by any CA under the corresponding `config.ca_certificates`. ### Matching behaviors -Once a client certificate has been verified as valid, the **Consumer** object will be determined in the following order unless `skip_consumer_lookup` is set to `true`: +After a client certificate has been verified as valid, the **Consumer** object is determined in the following order, unless `skip_consumer_lookup` is set to `true`: 1. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = ` 2. Manual mappings with `subject_name` matching the certificate's SAN or CN (in that order) and `ca_certificate = NULL` 3. If `config.consumer_by` is not null, Consumer with `username` and/or `id` matching the certificate's SAN or CN (in that order) 4. The `config.anonymous` consumer (if set) -**Note**: matching will stop as soon as the first successful match is found. +> **Note**: Matching stops as soon as the first successful match is found. When a client has been authenticated, the plugin will append headers to the request before proxying it to the upstream service so that you can identify the **Consumer** in your code: @@ -170,13 +210,7 @@ certificate property being set in `authenticated_group_by`. ### Troubleshooting -When authentication fails, the client does not have access to any details explaining the +When authentication fails, the client does not have access to any details that explain the failure. The security reason for this omission is to prevent malicious reconnaissance. Instead, the details are recorded inside Kong's error logs under the `[mtls-auth]` filter. - - -[configuration]: /latest/configuration -[consumer-object]: /latest/admin-api/#consumer-object -[acl-associating]: /plugins/acl/#associating-consumers -[faq-authentication]: /about/faq/#how-can-i-add-an-authentication-layer-on-a-microservice/api? diff --git a/app/_hub/kong-inc/proxy-cache-advanced/index.md b/app/_hub/kong-inc/proxy-cache-advanced/index.md index 58af83cd4837..c1baad6d51e3 100644 --- a/app/_hub/kong-inc/proxy-cache-advanced/index.md +++ b/app/_hub/kong-inc/proxy-cache-advanced/index.md @@ -49,7 +49,7 @@ params: default: text/plain, application/json value_in_examples: description: | - Upstream response content types considered cacheable. The plugin performs an exact match against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status will be returned. + Upstream response content types considered cacheable. The plugin performs an **exact match** against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status is returned. - name: vary_headers required: false default: @@ -152,6 +152,16 @@ params: value_in_examples: description: | Unhandled errors while trying to retrieve a cache entry (such as redis down) are resolved with `Bypass`, with the request going upstream. + extra: | + +
+ Warning: The content_type parameter requires + an exact match. For example, if your Upstream expects + application/json; charset=utf-8 and the + config.content_type value is only application/json + (a partial match), then the proxy cache is bypassed. +
+ --- ### Strategies diff --git a/app/_hub/kong-inc/proxy-cache/index.md b/app/_hub/kong-inc/proxy-cache/index.md index 390ae7ae63f5..d5e04e8534f8 100644 --- a/app/_hub/kong-inc/proxy-cache/index.md +++ b/app/_hub/kong-inc/proxy-cache/index.md @@ -54,7 +54,7 @@ params: default: '`["text/plain", "application/json"]`' value_in_examples: description: | - Upstream response content types considered cacheable. The plugin performs an exact match against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status will be returned. + Upstream response content types considered cacheable. The plugin performs an **exact match** against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status is returned. - name: vary_headers required: false default: @@ -97,6 +97,15 @@ params: value_in_examples: description: | The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template. + extra: | + +
+ Warning: The content_type parameter requires + an exact match. For example, if your Upstream expects + application/json; charset=utf-8 and the + config.content_type value is only application/json + (a partial match), then the proxy cache is bypassed. +
--- ### Strategies diff --git a/app/_hub/kong-inc/rate-limiting/index.md b/app/_hub/kong-inc/rate-limiting/index.md index 6709721d6a70..91bbeda6aca8 100644 --- a/app/_hub/kong-inc/rate-limiting/index.md +++ b/app/_hub/kong-inc/rate-limiting/index.md @@ -3,7 +3,7 @@ name: Rate Limiting publisher: Kong Inc. redirect_from: - /enterprise/0.35-x/rate-limiting/ -version: 2.2.0 +version: 2.2.x desc: Rate-limit how many HTTP requests can be made in a period of time description: | @@ -24,6 +24,7 @@ categories: kong_version_compatibility: community_edition: compatible: + - 2.2.x - 2.1.x - 2.0.x - 1.4.x @@ -93,10 +94,13 @@ params: required: false default: '`consumer`' description: | - The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`, `service`, `header`. If the `consumer`, the `credential`, or the `service` cannot be determined, the system will always fallback to `ip`. If value `header` is chosen, the `header_name` configuration has to be provided. + The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`, `service`, `header`, `path`. If the `consumer`, the `credential`, or the `service` cannot be determined, the system will always fallback to `ip`. If value `header` is chosen, the `header_name` configuration must be provided. If value `path` is choses, the `path` configuration must be provided. - name: header_name required: semi description: Header name to be used if `limit_by` is set to `header`. + - name: path + required: semi + description: Path to be used if `limit_by` is set to `path`. - name: policy required: false value_in_examples: "local" diff --git a/app/_hub/kong-inc/request-validator/index.md b/app/_hub/kong-inc/request-validator/index.md index 3ea7a08e29f9..92c59096abae 100755 --- a/app/_hub/kong-inc/request-validator/index.md +++ b/app/_hub/kong-inc/request-validator/index.md @@ -204,7 +204,7 @@ The `type` field assumes one the following values: - `array` - `record` -Each field specification may also contain "validators", which perform specific +Each field specification may also contain validators, which perform specific validations: | Validator | Applies to | Description | @@ -221,7 +221,7 @@ validations: | `starts_with` | Strings | True if the string value starts with the specified substring | | `one_of` | Strings, Numbers, Integers | True if the string field value matches one of the specified values | | `timestamp` | Integers | True if the field value is a valid timestamp | -| `uuid`| Strings | True if the string is a valud UUID | +| `uuid`| Strings | True if the string is a valid UUID | **Note**: To learn more, see [Lua patterns][lua-patterns]. @@ -315,7 +315,8 @@ Such a schema would validate the following request body: You can setup definitions for each parameter based on the OpenAPI Specification and the plugin will validate each parameter against it. For more information see the -[OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameter-object) or the [OpenAPI examples](https://swagger.io/docs/specification/serialization/). +[OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameter-object) +or the [OpenAPI examples](https://swagger.io/docs/specification/serialization/). #### Fixed Fields @@ -330,9 +331,9 @@ the plugin will validate each parameter against it. For more information see the #### Examples -In this example we will use the plugin to validate a request's path parameter. +In this example, use the plugin to validate a request's path parameter. -1. Add a service to Kong +1. Add a Service to Kong: ``` curl -i -X POST http://kong:8001/services \ @@ -358,7 +359,7 @@ In this example we will use the plugin to validate a request's path parameter. } ``` -2. Add a route with [named capture group](https://docs.konghq.com/latest/proxy/#capturing-groups) +2. Add a Route with [named capture group](https://docs.konghq.com/latest/proxy/#capturing-groups): ``` curl -i -X POST http://kong:8001/services/httpbin/routes \ @@ -394,7 +395,7 @@ In this example we will use the plugin to validate a request's path parameter. } ``` -3. Enable request-validator plugin to validate body and parameter +3. Enable request-validator plugin to validate body and parameter: ``` curl -i -X POST http://kong:8001/services/httpbin/plugins \ @@ -454,33 +455,34 @@ In this example we will use the plugin to validate a request's path parameter. } ``` - Here validation will make sure `status_code` is a number. +4. In these step examples, validation makes sure that `status_code` is a number. -4. A proxy request with a non-numerical status code will be blocked + A proxy request with a non-numerical status code is blocked: ``` curl -i -X GET http://kong:8000/status/abc HTTP/1.1 400 Bad Request - .. + ... {"message":"request param doesn't conform to schema"} ``` - but it will be allowed with a numeric status code + A proxy request with a numeric status code is allowed: ``` curl -i -X GET http://kong:8000/status/200 HTTP/1.1 200 OK X-Kong-Upstream-Latency: 163 X-Kong-Proxy-Latency: 37 - .. + ... ``` ### Further References The Kong schema validation format is based on the plugin schemas. -For more information, see the Kong plugin docs on [storing custom entities][schema-docs]. +For more information, see the Kong plugin docs on +[storing custom entities](/latest/plugin-development/custom-entities/#defining-a-schema). --- diff --git a/app/_hub/kong-inc/response-ratelimiting/index.md b/app/_hub/kong-inc/response-ratelimiting/index.md index 1eb6bbcaca1a..2b459bb61d45 100644 --- a/app/_hub/kong-inc/response-ratelimiting/index.md +++ b/app/_hub/kong-inc/response-ratelimiting/index.md @@ -5,9 +5,16 @@ version: 1.0.0 desc: Rate-limiting based on a custom response header value description: | - This plugin allows you to limit the number of requests a developer can make based on a custom response header returned by the upstream service. You can arbitrary set as many rate-limiting objects (or quotas) as you want and instruct Kong to increase or decrease them by any number of units. Each custom rate-limiting object can limit the inbound requests per seconds, minutes, hours, days, months or years. + This plugin allows you to limit the number of requests a developer can make + based on a custom response header returned by the upstream service. You can + arbitrarily set as many rate-limiting objects (or quotas) as you want and + instruct Kong to increase or decrease them by any number of units. Each custom + rate-limiting object can limit the inbound requests per seconds, minutes, hours, + days, months, or years. - If the underlying Service/Route (or deprecated API entity) has no authentication layer, the **Client IP** address will be used, otherwise the Consumer will be used if an authentication plugin has been configured. + If the underlying Service/Route (or deprecated API entity) has no authentication + layer, the **Client IP** address will be used; otherwise, the Consumer will be + used if an authentication plugin has been configured.
Note: The functionality of this plugin as bundled @@ -71,6 +78,7 @@ params: config: - name: limits.{limit_name} required: true + value_in_examples: description: This is a list of custom objects that you can set, with arbitrary names set in the `{limit_name`} placeholder, like `config.limits.sms.minute=20` if your object is called "SMS". - name: limits.{limit_name}.second required: semi @@ -110,7 +118,7 @@ params: - name: fault_tolerant required: false default: "`true`" - description: A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true` requests will be proxied anyways effectively disabling the rate-limiting function until the datastore is working again. If `false` then the clients will see `500` errors. + description: A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true`, requests will be proxied anyway, effectively disabling the rate-limiting function until the datastore is working again. If `false`, then the clients will see `500` errors. - name: hide_client_headers required: false default: "`false`" @@ -144,28 +152,33 @@ After adding the plugin, you can increment the configured limits by adding the f Header-Name: Limit=Value [,Limit=Value] ``` -Since `X-Kong-Limit` is the default header name (you can optionally change it), it will look like: +Because `X-Kong-Limit` is the default header name (you can optionally change it), +the request looks like: -``` -X-Kong-Limit: limitname1=2, limitname2=4 +```bash +$ curl -v -H 'X-Kong-Limit: limitname1=2, limitname2=4' ``` -That will increment the limit `limitname1` by 2 units, and `limitname2` by 4 units. +The above example increments the limit `limitname1` by 2 units, and `limitname2` by 4 units. -You can optionally increment more than one limit by comma separating the entries. The header will be removed before returning the response to the original client. +You can optionally increment more than one limit with comma-separated entries. +The header is removed before returning the response to the original client. ---- ## Headers sent to the client -When this plugin is enabled, Kong will send some additional headers back to the client telling how many units are available and how many are allowed. For example if you created a limit/quota called "Videos" with a per-minute limit: +When the plugin is enabled, Kong sends some additional headers back to the +client telling how many units are available and how many are allowed. + +For example, if you created a limit/quota called "Videos" with a per-minute limit: ``` X-RateLimit-Limit-Videos-Minute: 10 X-RateLimit-Remaining-Videos-Minute: 9 ``` -or it will return a combination of more time limits, if more than one is being set: +If more than one limit value is being set, it returns a combination of more time limits: ``` X-RateLimit-Limit-Videos-Second: 5 @@ -174,11 +187,15 @@ X-RateLimit-Limit-Videos-Minute: 10 X-RateLimit-Remaining-Videos-Minute: 10 ``` -If any of the limits configured is being reached, the plugin will return a `HTTP/1.1 429` status code and an empty body. +If any of the limits configured is being reached, the plugin +returns an `HTTP/1.1 429` (Too Many Requests) status code and an empty response body. ### Upstream Headers -The plugin will append the usage headers for each limit before proxying it to the upstream service, so that you can properly refuse to process the request if there are no more limits remaining. The headers are in the form of `X-RateLimit-Remaining-{limit_name}`, like: +The plugin appends the usage headers for each limit before proxying it to the +upstream service, so that you can properly refuse to process the request if there +are no more limits remaining. The headers are in the form of +`X-RateLimit-Remaining-{limit_name}`, for example: ``` X-RateLimit-Remaining-Videos: 3 diff --git a/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md b/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md index c079a5a11392..ab1c0c02325e 100755 --- a/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md +++ b/app/_hub/kong-inc/response-transformer-advanced/1.3-x.md @@ -40,9 +40,6 @@ params: - name: remove.if_status required: false description: List of response status codes or status code ranges to which the transformation will apply. Empty means all response codes. - - name: rename.headers - required: false - description: List of headername:value pairs. Renames header with headername to new name. - name: replace.headers required: false description: List of headername:value pairs. If and only if the header is already set, replace its old value with the new one. Ignored if the header is not already set. diff --git a/app/_hub/kong-inc/serverless-functions/index.md b/app/_hub/kong-inc/serverless-functions/index.md index 71bf7ee05362..d521ece76d54 100644 --- a/app/_hub/kong-inc/serverless-functions/index.md +++ b/app/_hub/kong-inc/serverless-functions/index.md @@ -9,6 +9,13 @@ desc: Dynamically run Lua code from Kong description: | Dynamically run Lua code from Kong. +
+ Warning: The pre-function and post-function serverless plugin + allows anyone who can enable the plugin to execute arbitrary code. + If your organization has security concerns about this, disable the plugin + in your kong.conf file. +
+ type: plugin categories: - serverless diff --git a/app/_hub/kong-inc/session/index.md b/app/_hub/kong-inc/session/index.md index 0aeffb96cad9..88d1c96f8aac 100644 --- a/app/_hub/kong-inc/session/index.md +++ b/app/_hub/kong-inc/session/index.md @@ -80,15 +80,15 @@ params: - name: cookie_samesite required: false default: 'Strict' - description: 'Determines whether and how a cookie may be sent with cross-site requests. `Strict`: the browser will send cookies only if the request originated from the website that set the cookie. `Lax`: same-site cookies are withheld on cross-domain subrequests, but will be sent when a user navigates to the URL from an external site, for example, by following a link. `None` or `off`: disables the same-site attribute so that a cookie may be sent with cross-site requests. For more info, see the [SameSite cookies docs on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite).' + description: 'Determines whether and how a cookie may be sent with cross-site requests. `Strict`: The browser will send cookies only if the request originated from the website that set the cookie. `Lax`: Same-site cookies are withheld on cross-domain subrequests, but will be sent when a user navigates to the URL from an external site, for example, by following a link. `None` or `off`: Disables the same-site attribute so that a cookie may be sent with cross-site requests. `None` requires the Secure attribute (`cookie_secure`) in latest browser versions. For more info, see the [SameSite cookies docs on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite).' - name: cookie_httponly required: false default: true - description: Applies the `HttpOnly` tag so that the cookie is sent only to a server https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Restrict_access_to_cookies + description: Applies the `HttpOnly` tag so that the cookie is sent only to a server. See the [Restrict access to cookies docs on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Restrict_access_to_cookies). - name: cookie_secure required: false default: true - description: Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Restrict_access_to_cookies + description: Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol. See the [Restrict access to cookies docs on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Restrict_access_to_cookies). - name: cookie_discard required: false default: 10 diff --git a/app/_hub/kong-inc/statsd/index.md b/app/_hub/kong-inc/statsd/index.md index 2bc7e68f1b72..85e4f3cc65c7 100644 --- a/app/_hub/kong-inc/statsd/index.md +++ b/app/_hub/kong-inc/statsd/index.md @@ -58,7 +58,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: host diff --git a/app/_hub/kong-inc/syslog/index.md b/app/_hub/kong-inc/syslog/index.md index 76165859bae0..5fa34689d0fc 100644 --- a/app/_hub/kong-inc/syslog/index.md +++ b/app/_hub/kong-inc/syslog/index.md @@ -48,7 +48,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: successful_severity diff --git a/app/_hub/kong-inc/tcp-log/index.md b/app/_hub/kong-inc/tcp-log/index.md index 95fc447d87f4..9973e2767642 100644 --- a/app/_hub/kong-inc/tcp-log/index.md +++ b/app/_hub/kong-inc/tcp-log/index.md @@ -60,7 +60,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: host diff --git a/app/_hub/kong-inc/udp-log/index.md b/app/_hub/kong-inc/udp-log/index.md index 0a1a2a19ea0a..c86139af0d40 100644 --- a/app/_hub/kong-inc/udp-log/index.md +++ b/app/_hub/kong-inc/udp-log/index.md @@ -52,7 +52,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ["http", "https", "grpc", "grpcs"] + protocols: ["http", "https", "grpc", "grpcs", "tcp", "tls", "udp"] dbless_compatible: yes config: - name: host diff --git a/app/_hub/kong-inc/zipkin/index.md b/app/_hub/kong-inc/zipkin/index.md index c1ab862fec4c..19f29f038a61 100644 --- a/app/_hub/kong-inc/zipkin/index.md +++ b/app/_hub/kong-inc/zipkin/index.md @@ -51,7 +51,7 @@ params: service_id: true route_id: true consumer_id: true - protocols: ['http', 'https', 'tcp', 'tls', 'grpc', 'grpcs'] + protocols: ['http', 'https', 'tcp', 'tls', 'udp', 'grpc', 'grpcs'] dbless_compatible: yes config: - name: http_endpoint diff --git a/app/_hub/plugins/compatibility/index.md b/app/_hub/plugins/compatibility/index.md index c83a7d2fc9f5..64155e7a6eca 100644 --- a/app/_hub/plugins/compatibility/index.md +++ b/app/_hub/plugins/compatibility/index.md @@ -30,8 +30,8 @@ nodes, so only control plane nodes require a database
Not supported
-| Plugin | Kong or Third-Party | Classic | DB-less | Hybrid mode | Notes {:width=40%:} | -|:-----------------------------------------------------------------------------------|:--------------------|:---------------------------:|:---------------------------------------------------------:|:---------------------------------------------------------:|:--| +| Plugin | Owner | Classic | DB-less | Hybrid mode | Notes {:width=40%:} | +|:--------|:------|:---------:|:--------:|:------------:|:--------------------| | [ACL](/hub/kong-inc/acl/) | Kong | | | | Authentication plugins can only be used if the set of credentials is static and specified as part of the declarative configuration. Admin API endpoints to dynamically create, update, or delete credentials are not available in DB-less mode. | | [ACME (Let's Encrypt)](/hub/kong-inc/acme/) | Kong | | | | | | [Apache OpenWhisk](/hub/kong-inc/openwhisk/) | Kong | | | | | @@ -72,8 +72,7 @@ nodes, so only control plane nodes require a database | [PASETO](/hub/peter-evans/paseto/) | Third-party | | | | Authentication plugins can only be used if the set of credentials is static and specified as part of the declarative configuration. Admin API endpoints to dynamically create, update, or delete credentials are not available in DB-less mode. | | [Prometheus](/hub/kong-inc/prometheus/) | Kong | | | | | | [Proxy Cache](/hub/kong-inc/proxy-cache/) | Kong | | | | | -| [Rate Limiting](/hub/kong-inc/rate-limiting/) | Kong | | | | The `cluster` policy is not supported in DB-less and hybrid modes. For DB-less mode, use one of `redis` or `local`; for hybrid mode, use `redis`. - | +| [Rate Limiting](/hub/kong-inc/rate-limiting/) | Kong | | | | The `cluster` policy is not supported in DB-less and hybrid modes. For DB-less mode, use one of `redis` or `local`; for hybrid mode, use `redis`. | | [Reedelk Transformer](/hub/reedelk/reedelk-transformer) | Third-party | | | | | | [Request Size Limiting](/hub/kong-inc/request-size-limiting) | Kong | | | | | | [Request Termination](/hub/kong-inc/request-termination) | Kong | | | | | @@ -100,9 +99,8 @@ nodes, so only control plane nodes require a database {% navtab Kong Enterprise %} {{site.ee_product_name}} can be deployed in the following ways: * **Classic:** Every node is connected to a database. Refers to a classic -deployment on any platform, including Kubernetes (Kong for Kubernetes with -Kong Enterprise). -* **Kong for Kubernetes Enterprise (K4K8s):** Deployed with the Kong Ingress +deployment on any platform, including Kubernetes. +* **DB-less Kong Enterprise on Kubernetes:** Deployed with the Kong Ingress Controller and no database. * **Hybrid mode:** Nodes are split into control plane and data plane roles. The control plane coordinates configuration and propagates it to data plane @@ -120,8 +118,8 @@ and [{{site.ee_product_name}} for Kubernetes Deployment Options](/enterprise/lat
Not supported
-| Plugin | Kong or Third-Party | Classic and K4K8s with Kong Enterprise | K4K8s | Hybrid Mode | Notes {:width=30%:} | -|:-----------------------------------------------------------------------------------|:--------------------|:--------------------------------------:|:---------------------------------------------------------:|:---------------------------------------------------------:|:--| +| Plugin | Owner | Classic | DB-less Kong Enterprise on K8S | Hybrid Mode | Notes {:width=30%:} | +|:--------|:------|:--------:|:-------------------------------------:|:---------------:|:--------------------| | [ACL](/hub/kong-inc/acl/) | Kong | | | | | | [Apache OpenWhisk](/hub/kong-inc/openwhisk/) | Kong | | | | | | [Approov API Threat Protection](/hub/critical-blue/approov/) | Third-party | | | | | @@ -167,19 +165,19 @@ and [{{site.ee_product_name}} for Kubernetes Deployment Options](/enterprise/lat | [Okta](/hub/okta/okta/) | Third-party | | | | | | [OpenID Connect](/hub/kong-inc/openid-connect/) | Kong | | | | | | [PASETO](/hub/peter-evans/paseto/) | Third-party | | | | | -| [Portal Application Registration](/hub/kong-inc/application-registration) | Kong | | | | This plugin is only used with the Developer Portal, which is not available with K4K8s. | +| [Portal Application Registration](/hub/kong-inc/application-registration) | Kong | | | | This plugin is only used with the Developer Portal, which is not available with Kong Enterprise on Kubernetes in DB-less mode. | | [Prometheus](/hub/kong-inc/prometheus/) | Kong | | | | | | [Proxy Cache](/hub/kong-inc/proxy-cache/) | Kong | | | | | | [Proxy Caching Advanced](/hub/kong-inc/proxy-cache-advanced/) | Kong | | | | | -| [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced) | Kong | | | | The plugin does not support the `cluster` strategy in hybrid mode. The `redis` strategy must be used instead. | +| [Rate Limiting Advanced](/hub/kong-inc/rate-limiting-advanced) | Kong | | | | The `cluster` policy is not supported in DB-less and hybrid modes. For Kong Enterprise on Kubernetes in DB-less mode, use one of `redis` or `local`; for hybrid mode, use `redis`. | | [Reedelk Transformer](/hub/reedelk/reedelk-transformer) | Third-party | | | | | | [Request Size Limiting](/hub/kong-inc/request-size-limiting) | Kong | | | | | | [Request Termination](/hub/kong-inc/request-termination) | Kong | | | | | -| [Request Transformer Advanced](/hub/kong-inc/request-transformer-advanced/) | Kong | | | | Request Transformer now has feature parity with Request Transformer Advanced.

Request Transformer Advanced remains only for compatibility with existing configurations. | +| [Request Transformer Advanced](/hub/kong-inc/request-transformer-advanced/) | Kong | | | | Request Transformer now has feature parity with Request Transformer Advanced.

Request Transformer Advanced remains only for compatibility with existing configurations. | | [Request Transformer](/hub/kong-inc/request-transformer) | Kong | | | | | | [Request Validator](/hub/kong-inc/request-validator) | Kong | | | | | | [Response Rate Limiting](/hub/kong-inc/response-ratelimiting) | Kong | | | | | -| [Response Transformer Advanced](/hub/kong-inc/response-transformer-advanced/) | Kong | | | | Response Transformer now has feature parity with Response Transformer Advanced.

Response Transformer Advanced remains only for compatibility with existing configurations. | +| [Response Transformer Advanced](/hub/kong-inc/response-transformer-advanced/) | Kong | | | | | | [Response Transformer](/hub/kong-inc/response-transformer) | Kong | | | | | | [Route By Header](/hub/kong-inc/route-by-header/) | Kong | | | | | | [Route Transformer Advanced](/hub/kong-inc/route-transformer-advanced/) | Kong | | | | | @@ -188,8 +186,8 @@ and [{{site.ee_product_name}} for Kubernetes Deployment Options](/enterprise/lat | [Session](/hub/kong-inc/session/) | Kong | | | | | | [Signal Sciences](/hub/signal_sciences/signal-sciences) | Third-party | | | | | | [SignalFx](/hub/signalfx/signalfx/) | Third-party | | | | | -| [StatsD Advanced](/hub/kong-inc/statsd-advanced/) | Kong | | | | | -| [StatsD](/hub/kong-inc/statsd/) | Kong | | | | This plugin is only used with Vitals, which is not available with K4K8s. | +| [StatsD Advanced](/hub/kong-inc/statsd-advanced/) | Kong | | | | | +| [StatsD](/hub/kong-inc/statsd/) | Kong | | | | | | [Syslog](/hub/kong-inc/syslog/) | Kong | | | | | | [TCP Log](/hub/kong-inc/tcp-log/) | Kong | | | | | | [Template Transformer](/hub/stone-payments/kong-plugin-template-transformer) | Third-party | | | | | diff --git a/app/_hub/yesinteractive/kongmap/index.md b/app/_hub/yesinteractive/kongmap/index.md new file mode 100644 index 000000000000..f51a032da500 --- /dev/null +++ b/app/_hub/yesinteractive/kongmap/index.md @@ -0,0 +1,138 @@ +--- +name: KongMap +publisher: Yes Interactive + +categories: + - deployment + +type: integration + +desc: Visually Map and Manage your Kong Clusters + +description: | + Kongmap is a free visualization tool that allows you to view and edit configurations of your Kong API Gateway Clusters, including Routes, Services, and Plugins/Policies. The tool is being offered for installation using Docker and Kubernetes at this time. + +support_url: https://github.com/yesinteractive/kong-map/issues + +source_url: https://github.com/yesinteractive/kong-map + +license_type: AGPL-3.0 + +kong_version_compatibility: + community_edition: + compatible: + - 2.1.x + - 2.0.x + - 1.5.x + - 1.4.x + - 1.3.x + + enterprise_edition: + compatible: + - 2.1.x + - 1.5.x + - 1.3-x + + +############################################################################### +# END YAML DATA +# Beneath the next --- use Markdown (redcarpet flavor) and HTML formatting only. +# +# The remainder of this file is for free-form description, instruction, and +# reference matter. +# Your headers must be Level 3 or 4 (parsing to h3 or h4 tags in HTML). +# This is represented by ### or #### notation preceding the header text. +############################################################################### +# BEGIN MARKDOWN CONTENT +--- + +## Features + +#### Cluster View +Allows an admin to view a dynamic map of their Kong API Gateway clusters and visually see relationships between +Workspaces (for Kong Enterprise), Services, Routes (Endpoints), and Plugins (Policies). Clicking on any entity displays +details of the entity and related links. Plugins can be toggled from view. + + +![alt text](https://github.com/yesinteractive/kong-map/blob/main/screenshots/kongmap-home.png?raw=true "kongmap") + +#### Endpoint Analyzer +View details of an API Endpoint (Route). The analyzer shows the Service attached to the endpoint/route as well as +a breakdown of all plugins/policies in order of execution attached to the route/endpoint. For Kong Enterprise users, +all entities can be viewed directly via a link to Kong Manager. + +![alt text](https://github.com/yesinteractive/kong-map/blob/main/screenshots/kongmap-endpoint.png?raw=true "kongmap") + + +#### Declarative Configuration Viewer/Editor +KongMap is deployed with a browser-based version of Kong's CLI tool, decK. Here you can view, edit, and export Kong declarative configurations for your open source +and Enterprise clusters via YAML. Declarative +configuration editing can be disabled by KongMap configuration, or managed with RBAC permissions if using Kong Enterprise. + +![alt text](https://github.com/yesinteractive/kong-map/blob/main/screenshots/kongmap-deck.png?raw=true "kongmap") + + +Full documentation is available here: [https://github.com/yesinteractive/kong-map/](https://github.com/yesinteractive/kong-map/) + +## Compatibility ## +KongMap supports both Kong Open Source and Kong Enterprise Clusters greater than version 1.5. + +## Docker Installation ## + +Docker image is Alpine 3.11 based running PHP 7.3 on Apache. The container exposes both ports 80 an 443 with a self-signed certificated. + +#### 1. Export Cluster Configurations to Variable #### + +The connections to your Kong clusters are defined using JSON. The below example illustrates adding two Kong clusters to KongMap: + +```json +{ + "my enterprise cluster": { + "kong_admin_api_url": "http://kongapi_url:8001", + "kong_edit_config": "true", + "kong_ent": "true", + "kong_ent_token": "admin", + "kong_ent_token_name": "kong-admin-token", + "kong_ent_manager_url": "http://" + }, + "my kong open source cluster": { + "kong_admin_api_url": "http://kongapi_url:8001", + "kong_edit_config": "true", + "kong_ent": "false", + "kong_ent_token": "null", + "kong_ent_token_name": "null", + "kong_ent_manager_url": "null" + } +} + ``` + +Notice the `kong_ent` configurations. Enable and configure this if the cluster you are configuring is Kong Cluster. If you do not, only the Default workspace +will be visible in your Kong Enterprise Cluster. + +Export the config to a variable: + +```shell + export KONG_CLUSTERS='{ "my enterprise cluster": { "kong_admin_api_url": "http://kongapi_url:8001", "kong_edit_config": "true", "kong_ent": "true", "kong_ent_token": "admin", "kong_ent_token_name": "kong-admin-token", "kong_ent_manager_url": "http://kongmanager_url:8002" }}' + ``` + +#### 2. Start Container #### + +Run the container with the following command. Set the ports to your preferred exposed ports. The example below exposes KongMap on ports 8100 and 8143. Notice the `KONGMAP_URL` variable. Set this optional variable if you have a need to set all KongMap URL's to a specific domain or URL. + +``` +$ docker run -d \ + -e "KONGMAP_CLUSTER_JSON=$KONG_CLUSTERS" \ + -e "KONGMAP_URL=http://url_to_kongmap" \ + -p 8100:80 \ + -p 8143:443 \ + yesinteractive/kongmap +``` + +#### 3. Authentication #### + +If you want to enable authentication to KongMap's UI, it is recommended to run Kongmap behind your Kong Gateway and implement any authentication +policies you feel are appropriate (OIDC, OAUTH2, Basic Auth, etc.) at the gateway. + +## Feedback and Issues + +If you have questions, feedback, or want to submit issues, please do so here: [https://github.com/yesinteractive/kong-map/issues](https://github.com/yesinteractive/kong-map/issues). diff --git a/app/_includes/footer.html b/app/_includes/footer.html index d41cfdc7b88a..f295911efc2e 100644 --- a/app/_includes/footer.html +++ b/app/_includes/footer.html @@ -3,8 +3,13 @@