Skip to content

Commit

Permalink
decK guides (#79)
Browse files Browse the repository at this point in the history
* port some decK guides over to fill the how-to guides filter on landing page

* move a bunch of stuff to references

* clean up defaults guide; set api-ops as product; add distributed config reference

* fix guide names

* combine two steps of tutorial into one

* remove markdownify filter from tldr since none of them are long

* remove entity setup from prereqs, rewrote the guide in a way that they're not needed

* update product key to products

* fix typo

* Filter how-tos by tools too

* Pass `products` to how_to_list config

* Check if include exists for a product's prereq before rendering it
instead of making the build fail

* Fix collapsible steps in how-tos when there's a section without a title

* Update admonition styles

* Use new css classes for admonitions

* Add no-copy to code snippet

* Make include_exists evaluate the file name in case it's a variable and
fix view to use the correct variable

* Add api-ops product data

---------

Co-authored-by: Fabian Rodriguez <[email protected]>
  • Loading branch information
lena-larionova and fabianrbz authored Sep 19, 2024
1 parent 9c8f54d commit 3b6d419
Show file tree
Hide file tree
Showing 12 changed files with 679 additions and 10 deletions.
4 changes: 2 additions & 2 deletions app/_assets/stylesheets/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@
}

.success, .warning, .danger, .info, .neutral {
@apply rounded-md p-4 gap-2 border-l-[3px] text-primary flex;
@apply rounded-md p-4 gap-2 border-l-[3px] text-primary flex flex-col pl-11 relative;

&:not(.no-icon)::before {
@apply text-base content-['\f05a'];
@apply text-base content-['\f05a'] absolute left-4;
font-family: "Font Awesome", FontAwesome;
}
}
Expand Down
1 change: 1 addition & 0 deletions app/_data/products/api-ops.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: APIOps
119 changes: 119 additions & 0 deletions app/_how-tos/custom-deck-object-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
title: Customize object defaults in decK

works_on:
- on-prem
- konnect

products:
- api-ops

tools:
- deck

related_resources:
- text: decK object defaults reference
url: /deck/object-defaults

tldr:
q: |
How do I set custom default values for Kong Gateway entities?
a: |
You can configure your own custom Kong Gateway defaults via decK to
enforce a set of standard values and avoid repetition in your configuration.
---

You can set custom configuration defaults for the following core
{{site.base_gateway}} objects:
- Service
- Route
- Upstream
- Target

Default values get applied to both new and existing objects. See the
[order of precedence](/deck/object-defaults/#value-order-of-precedence) for more detail on how they
get applied.

You can choose to define custom default values for any subset of entity fields,
or define all of them. decK still finds the default values using a
combination of your defined fields and the object's schema, based on the
order of precedence.

decK supports setting custom object defaults both in self-managed
{{site.base_gateway}} and with {{site.konnect_saas}}.

{:.warning}
> **Important:** This feature has the following limitations:
* Custom plugin object defaults are not supported.
* If an existing property's default value changes in a future {{site.base_gateway}} release,
decK has no way of knowing that this change has occurred, as its `defaults`
configuration would overwrite the value in your environment.

## 1. Define default properties

Define the properties you want to customize for {{site.base_gateway}} objects.
See the [object defaults reference](/deck/object-defaults) for all configurable objects and default values.

In the `deck_files` directory you created in the [prerequisites](#prerequisites), create a `defaults.yaml` file
and add an `_info` section with `defaults`.
You can define a few select properties for a supported entity, such as a service:

```yaml
_format_version: "3.0"
_info:
defaults:
service:
port: 8080
protocol: https
retries: 10
```
{: data-file="defaults.yaml" }
Or you could define custom default values for all available fields of a service and a route:
```yaml
_format_version: "3.0"
_info:
defaults:
route:
https_redirect_status_code: 426
path_handling: v1
preserve_host: false
protocols:
- http
- https
regex_priority: 0
request_buffering: true
response_buffering: true
strip_path: true
service:
port: 8080
protocol: https
connect_timeout: 60000
write_timeout: 60000
read_timeout: 60000
retries: 10
```
{: data-file="defaults.yaml" }
## 2. Validate
Sync your changes with {{site.base_gateway}}:
```sh
deck gateway sync kong.yaml
```

Response:
```sh
Summary:
Created: 0
Updated: 0
Deleted: 0
```
{:.no-copy-code}

Whether you choose to define a subset of custom defaults or all available
options, the result is the same: the diff summary doesn't show any changes,
because no entities have actually changed in the database.
11 changes: 7 additions & 4 deletions app/_includes/components/prereqs.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<div class="flex flex-col accordion" data-default="0">
{% if page.products %}
{% for product in page.products %}
<div class="flex flex-col px-5 py-4 gap-1.5 border-b border-primary/5 accordion-item last:border-b-0">
{% assign product_include = 'prereqs/products/' | append: product | append: '.md' %}
{% include {{ product_include }} tier=include.tier %}
</div>
{% assign product_include = 'prereqs/products/' | append: product | append: '.md' %}
{% capture product_include_exists %}{% include_exists product_include %}{% endcapture %}
{% if product_include_exists == 'true' %}
<div class="flex flex-col px-5 py-4 gap-1.5 border-b border-primary/5 accordion-item last:border-b-0">
{% include {{ product_include }} tier=include.tier %}
</div>
{% endif %}
{% endfor %}
{% endif %}

Expand Down
4 changes: 3 additions & 1 deletion app/_landing_pages/deck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ rows:
- blocks:
- type: tabs
config:
- title: OSX (Homebrew)
- title: OSX
include_content: tools/deck/install/osx
- title: Windows
include_content: tools/deck/install/windows
Expand Down Expand Up @@ -318,6 +318,8 @@ rows:
- blocks:
- type: how_to_list
config:
products:
- "api-ops"
tools:
- deck
quantity: 5
Expand Down
13 changes: 11 additions & 2 deletions app/_plugins/hooks/sections/how-to.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ def section_title(h2, slug, title)
end

def build_wrapper(section_title = '')
Nokogiri::HTML::DocumentFragment.parse <<-HTML
<div class="flex flex-col gap-4 border-b border-primary/5 pb-8 accordion-item" aria-expanded="true">
wrapper = if section_title != ''
<<-HTML
<div class="flex flex-col gap-4 border-b border-primary/5 pb-8 accordion-item">
#{section_title}
<div class="content accordion-panel"></div>
</div>
HTML
else
<<-HTML
<div class="flex flex-col gap-4 border-b border-primary/5 pb-8">
<div class="content"></div>
</div>
HTML
end
Nokogiri::HTML::DocumentFragment.parse(wrapper)
end
end
end
3 changes: 2 additions & 1 deletion app/_plugins/tags/how_to_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ def render(context)

how_tos = @site.collections['how-tos'].docs.inject([]) do |result, t|
match = (!config.key?('tags') || t.data.fetch('tags', []).intersect?(config['tags'])) &&
(!config.key?('products') || t.data.fetch('products', []).intersect?(config['products']))
(!config.key?('products') || t.data.fetch('products', []).intersect?(config['products'])) &&
(!config.key?('tools') || t.data.fetch('tools', []).intersect?(config['tools']))

result << t if match
break result if result.size == quantity
Expand Down
16 changes: 16 additions & 0 deletions app/_plugins/tags/include_exists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Jekyll
class IncludeExistsTag < Liquid::Tag
def initialize(tag_name, file, tokens)
super
@file = file.strip
end

def render(context)
site_source = context.registers[:site].source
file_path = File.join(site_source, '_includes', context[@file])
File.exist?(file_path).to_s
end
end
end

Liquid::Template.register_tag('include_exists', Jekyll::IncludeExistsTag)
115 changes: 115 additions & 0 deletions app/deck/distributed-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
title: Distributed Configuration for Kong using decK

content_type: reference
layout: reference

works_on:
- on-prem
- konnect

productss:
- api-ops

tools:
- deck
---

decK can operate on a subset of configuration instead of
managing the entire configuration of {{site.base_gateway}}.
You can do this by breaking up the configuration into multiple files and managing them using tags.

With tags, you can use decK's `select-tag` feature to export, sync, or reset
only a subset of configuration.

## Use cases

Distributed configuration management can be very useful in a variety of scenarios.
For example:

| Use case | Description |
|----------|-------------|
| Single Kong installation whose configuration is built by multiple teams | For example, one team manages the inventory API, while another team manages the users API. Both APIs are exposed via {{site.base_gateway}}. <br> Team Inventory needs to manage its configuration without worrying about the configuration of the other team, and vice versa. The two teams can push out configuration changes on their own schedules. |
| Very large configuration | You have a large set of entities - hundreds, maybe thousands - and it's very difficult to manage them all in one file. You can use decK to break up the configuration into different files with specific purposes. |
| Separation of consumer management | You want to declaratively manage all of the configuration for Kong except consumers and their credentials. This could be for any number of reasons: <br> - The consumers are being managed by another service <br> - The consumers are dynamically created <br> - The number of consumers is so large that it makes no sense to manage them in a declarative fashion |

## Methods for managing distributed configuration

### Tags

Tags provide a way to associate metadata with entities
in {{site.base_gateway}}. You can also filter entities by tags on the list endpoints in {{site.base_gateway}}.

Using this feature, decK associates tags with entities and can manage a group
of entities which share a common tag(s).

When multiple tags are specified in decK, decK `AND`s those tags together,
meaning only entities containing all the tags will be managed by decK.
You can specify a combination of up to 5 tags, but we recommend using
fewer or only one tag, for performance reasons in Kong's codebase.

### Gateway dump

You can export a subset of entities in {{site.base_gateway}} by specifying common tags
using the `--select-tag` flag.

For example, the following command generates a `kong.yaml` file with all entities
which have both of the specified tags:

```shell
deck gateway dump --select-tag foo-tag --select-tag bar-tag
```

If you observe the file generated by decK, you will see the following section:

```yaml
_info:
select_tags:
- foo-tag
- bar-tag
```
This sub-section tells decK to filter out entities containing select-tags during
a sync operation.
### Gateway sync
You don't need to specify `--select-tag` in `sync` and `diff` commands.
The commands will use the tags present in the state file and perform the diff
accordingly.

Since the state files contain the tagging information, different teams can
make updates to the part of configuration in Kong without worrying about
configuration of other teams. You no longer need to maintain Kong's
configuration in a single repository, where multiple teams need to
co-ordinate.

The `--select-tag` flag is present on those two commands for use cases where
the file cannot have `select_tags` defined inside it. It is strongly advised
that you do not supply select-tags to sync and diff commands via flags.
This is because the tag information should be part of the declarative
configuration file itself in order to provide a practical declarative file.
The tagging information and entity definitions should be present in one place,
else an error in supplying the wrong tag via the CLI can break the
configuration.

### Gateway reset

You can delete only a subset of entities sharing a tag using the `--select-tag`
flag on the `gateway reset` command.

## Troubleshooting initial setup

When you initially get started with a distributed configuration
management, you will likely run into a problem where the related entities
you would like to manage don't share a single database.

To get around this problem, you can use one of the following approaches:

- Go through each entity in Kong, and patch those entities with the common
tag(s) you'd like, then use decK's `dump` command to export by different
tags.
- Export the entire configuration of Kong, and divide up the configuration
into different files. Then, add the `select_tags` info to the file.
This will require re-creation of the database now, since decK will not
detect any of the entities present (as they are missing the common tag).
Loading

0 comments on commit 3b6d419

Please sign in to comment.