# Take over an existing gateway

> The configuration of an existing gateway is taken over once, offline: Flexway never reads one at start - two sources of truth always drift apart. The contract…

Guide - Since version 1.2.0 - Flexway v1.6.3 - https://flexway.io/en/docs/operations-import/

> Operations guide: configure, deploy and observe the gateway. What the capability does, product side: [product guide](https://flexway.io/en/docs/product-overview/); calling it: [developer guide](https://flexway.io/en/docs/developer-overview/).

The configuration of an existing gateway is taken over **once, offline**: Flexway never reads one at
start - two sources of truth always drift apart. The contract stays the source: the import completes
it and invents nothing in it.

**Supported input format**: KrakenD's JSON configuration file (`krakend.json`), read by the
`flexway import krakend` command.

```bash
flexway import krakend --config krakend.json --contract openapi.yaml --out ./import
# or, from the published image (the output directory belongs to the current user):
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/w" -w /w ghcr.io/flexwiz/flexway:<version> \
  import krakend --config krakend.json --contract openapi.yaml --out import
```

`--out` is an empty or absent directory: the import never overwrites. It writes four files there,
after passing them to the **start's loader** - never a configuration that would refuse to start:

| File | Content |
| --- | --- |
| `flexway.yaml` | Upstreams, global timeout, issuers, policies; no operation listed |
| `openapi.yaml` (the name of the contract read) | The annotated contract: `x-flexway-*` and, when needed, `security` added; comments kept, JSON kept JSON |
| `contract.patch.json` | The same additions as a JSON Patch (RFC 6902), for whoever keeps the contract elsewhere |
| `coverage.md` | Every element of the imported configuration classified **taken over**, **taken over differently** (with the equivalent) or **no equivalent** (with the reason), a total per category; the endpoints absent from the contract; the operations no endpoint covers |

| Exit code | Meaning |
| --- | --- |
| `0` | Everything taken over |
| `3` | Taken over, with elements that have no equivalent: read `coverage.md` before serving |
| `1` | Refused, nothing written: unreadable file, invalid contract, a result the loader refuses (the message says why) |
| `2` | Malformed command line |

**Mapping**:

| Key of the imported configuration | Flexway | Category |
| --- | --- | --- |
| `endpoint` + `method` | The contract operation with the same method and template, parameter names aside (`{id}` = `{orderId}`); absent: **listed**, never invented | taken over |
| `backend[0].host` + `url_pattern` | `upstreams.<host>` (one per distinct host) + `x-flexway-upstream`; a `rewrite-path` policy when the path differs, parameters renamed | taken over, taken over differently |
| Several `host` | The first one; balancing is the platform's (a `Service`, the mesh) | no equivalent |
| Several `backend` (aggregation), `sd: dns`, `{JWT.sub}` in `url_pattern` | No upstream given: the loader refuses, code `1` | no equivalent |
| `timeout` (global, endpoint) | `server.timeouts.total`; an endpoint's that differs -> `x-flexway-timeout` | taken over |
| `input_headers`, `input_query_strings` | Nothing: closed by default, the contract declares; a name it does not declare is reported (a header is no longer relayed, a parameter is refused) | taken over differently, no equivalent |
| `auth/validator` | `auth.issuers` (discovery from `issuer`, `audience`, `alg`, `roles_key`, `scopes_key`); `security` added to an operation that declares none, one alternative per role; a contract less strict than the imported configuration is reported, never changed | taken over differently |
| `qos/ratelimit/router` | `client_max_rate` -> a `rate-limit` policy, per caller and operation; `max_rate` (all callers): no equivalent | taken over, no equivalent |
| `qos/circuit-breaker` | `upstreams.<name>.circuit_breaker`: `failure_ratio: 1`, `min_requests: max_errors + 1`, `window`, `cooldown`; one per upstream | taken over differently |
| `output_encoding`, `encoding`: `no-op`, `json` | Relayed as received | taken over differently |
| `allow` | `transform-body`, `project`, `on_missing: omit` | taken over differently |
| `deny`, `flatmap_filter` `del` | `redact`, `remove: true` | taken over differently |
| `mapping`, `group`, `target`, `is_collection`, `flatmap_filter` `move` | - | no equivalent |
| `validation/json-schema` | The contract's schema validates the body | taken over differently |
| `modifier/lua-*`, `plugin/*` | None: a native plugin or script is refused | no equivalent |
| Any other key | Reported, with the equivalent to write by hand when there is one (`security/cors` -> a `cors` policy, `qos/http-cache` -> `x-flexway-cache`) | no equivalent |

Then: read `coverage.md`, copy the annotated contract to where the contract lives, then
`flexway validate`. A **flexible** configuration (Go templates) is rendered first with the original
gateway's tool; the rendered file is what is imported:

```bash
krakend check -d
```

*Available since `1.2.0`.*
